digdug(地図系ゲーム)
code:digdug.py
import pyxel
import random
class App:
MAX_X = 200
MAX_Y = 200
CELL_SIZE = 10
score = 0
# キャラクター
class Character:
def __init__(self):
self.x = App.CELL_SIZE / 2
self.y = App.CELL_SIZE / 2
def update(self, soil):
# WASDで上下左右操作を可能にする
# 画面をはみ出た場合は元の場所に戻す処理を同時に実施している
if pyxel.btn(pyxel.KEY_W) and self.y > App.CELL_SIZE:
self.y -= App.CELL_SIZE
self.y += App.CELL_SIZE
elif pyxel.btn(pyxel.KEY_S) and self.y < 200 - App.CELL_SIZE:
self.y += App.CELL_SIZE
self.y -= App.CELL_SIZE
elif pyxel.btn(pyxel.KEY_A) and self.x > App.CELL_SIZE:
self.x -= App.CELL_SIZE
self.x += App.CELL_SIZE
elif pyxel.btn(pyxel.KEY_D) and self.x < 200 - App.CELL_SIZE:
self.x += App.CELL_SIZE
self.x -= App.CELL_SIZE
def draw(self):
# 自キャラを描画
pyxel.circ(self.x, self.y, App.CELL_SIZE / 2, 1)
# 土
class Soil:
# 地図上に描画されるものの種類を数字で表現
EMPTY = 0 # 掘られた地面
SOIL = 1 # 土
ROCK = 2 # 岩
FRUIT = 3 # フルーツ
def __init__(self):
# マップを生成
# field_map510 = 2 のように、各マスの中心座標に対して self.field_map = {}
for x in range(int(App.CELL_SIZE / 2), App.MAX_X, App.CELL_SIZE):
# x座標系を生成
for y in range(int(App.CELL_SIZE / 2), App.MAX_Y, App.CELL_SIZE):
# y座標系を生成
if random.randint(0, 100) < 5:
# 5%の確率で土でなくフルーツに
self.field_mapxy = self.FRUIT elif random.randint(0, 100) < 5:
# 5%の確率で岩に
self.field_mapxy = self.ROCK else:
# フルーツ出ない場合は全て土に
self.field_mapxy = self.SOIL def update(self, app, character):
# スコア更新および当たり判定をするためにアプリ本体およびキャラクターの情報を受取る
# フルーツと接触したらappのスコアを増やす
app.score += 100
# キャラクターがいる場所の土は掘られて空になる
def draw(self):
# マップ情報を描画していく
for x in self.field_map:
for y in self.field_mapx: # 土はピンク(14)で描画
if self.field_mapxy == self.SOIL: pyxel.rect(
x - App.CELL_SIZE / 2, y - App.CELL_SIZE / 2, App.CELL_SIZE, App.CELL_SIZE, 14)
# フルーツは水色(12)で描画
if self.field_mapxy == self.FRUIT: pyxel.rect(
x - App.CELL_SIZE / 2, y - App.CELL_SIZE / 2, App.CELL_SIZE, App.CELL_SIZE, 12)
# フルーツは黄色(10)で描画
if self.field_mapxy == self.ROCK: pyxel.rect(
x - App.CELL_SIZE / 2, y - App.CELL_SIZE / 2, App.CELL_SIZE, App.CELL_SIZE, 10)
def __init__(self):
pyxel.init(App.MAX_X, App.MAX_Y, caption="DiGDUG")
self.character = self.Character()
self.soil = self.Soil()
self.score = 0
self.complete = False
pyxel.run(self.update, self.draw)
def is_cleared(self, soil):
# マップ上にフルーツが存在する限りは未クリア
for x in soil.field_map:
for y in soil.field_mapx: if soil.field_mapxy == soil.FRUIT: return False
return True
def update(self):
# q を押されたら終了
if pyxel.btn(pyxel.KEY_Q):
pyxel.quit()
# キャラクターのデータ更新
self.character.update(self.soil)
# マップのデータ更新
self.soil.update(self, self.character)
# クリア判定
self.complete = self.is_cleared(self.soil)
def draw(self):
pyxel.cls(0)
if self.complete:
pyxel.text(0, 100, "Congratz!!! your score was " +
str(self.score), 7)
else:
self.soil.draw()
self.character.draw()
pyxel.text(0, 0, "score:" + str(self.score), 7)
App()
マップ描画に関して
1マスの幅を CELL_SIZEによって定義 (=10)
画面サイズは200 x 200 なので全部で 20 * 20 = 400個のマスを管理
field_mapの中身は以下のようになっている