KUNISAN.JPトップ

Python関連記事 - 連続表示

新規書き込み


※該当の記事タイトル一覧はリンク一覧から参照できます。

Python - リスト内包表記とPygameのスプライト機能

名前: 小川 邦久 リンク: http://kunisan.jp/ 日付: 2017年12月2日



Python - リスト内包表記とPygameのスプライト機能先日のPythonミニゲーム(DOG & BURGERS)の後、Webサーバー上で動くプログラムを作成しようと思っていました。しかし、その前にやっておきたいことが2点あったので、今回はそれを試す目的でサンプルプログラムを作成してみました。

以下、ソースコードです。

-------------------------
""" list_comprehension_sprite.py """

import math
import pygame
from pygame.locals import *
import sys

pygame.init()
SCR_RECT = Rect(0,0,400,300)
SURFACE = pygame.display.set_mode(SCR_RECT.size)
FPSCLOCK = pygame.time.Clock()

pygame.display.set_caption("Sunflowers")

class MySprite(pygame.sprite.Sprite):
""" スプライト定義 """
def __init__(self, filename, x=0, y=0):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(filename)
self.width = self.image.get_width()
self.height = self.image.get_height()
self.x = x
self.y = y
self.rect = Rect(self.x, self.y, self.width, self.height)
#スプライト表示
def locate(self, x = 9999, y = 9999):
if x < 9999:
self.x = x
if y < 9999:
self.y = y
self.rect = Rect(self.x, self.y, self.width, self.height)

def main():
""" メインルーチン """

#三角関数結果をリスト化(内包表記)
circle_x = [math.cos(math.pi/180*i) for i in range(360)]
circle_y = [math.sin(math.pi/180*i) for i in range(360)]

#スプライトグループ作成
sprites = pygame.sprite.Group()

#ひまわりスプライト定義(リスト)
sunflowers = []
for i in range(10):
sunflowers.append(0)
sunflowers[i] = MySprite("sunflowers.gif", circle_x[i*36]*100+200, circle_y[i*36]*100+200)
sprites.add(sunflowers[i])

#変数初期設定
circle_counter = 0
a = 0

while True:

#ウインドウ閉じるボタン
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()

#画面塗りつぶし
SURFACE.fill((0,0,0))

#角度カウンター
circle_counter += 1
if circle_counter >= 360:
circle_counter = 0

#ひまわり座標計算
for i in range(10):
a = circle_counter + i * 36
if a >= 360:
a -= 360
sunflowers[i].locate(circle_x[a]*100+175, circle_y[a]*110+125)

#スプライトグループ表示
sprites.draw(SURFACE)

#画面アップデート
pygame.display.update()
FPSCLOCK.tick(100)

if __name__ == '__main__':
main()
-------------------------


ファイル一式はこちらからダウンロードできます
※本プログラムやファイルの二次配布や二次掲載はご遠慮ください。個人的なプログラム改造はご自由にどうぞ。ただし、本プログラムに関するご質問等はお受けしません。

まずはリスト内包表記(List Comprehension)です。

今から30年近く前(高校2年でした)、X68000であるゲームを作っている時に、円運動するキャラクターを設置しようと思いつきました。シンプルに三角関数(サイン/sin、コサイン/cos)で座標を決めればいいと思っていたのですが、当時のパソコンは今のものに比べて処理速度が貧弱ということもあり、キャラクターを複数設置すると三角関数の繰り返しの計算の影響で、動作に遅延が起きるようになってしまいました。そこで考えついたのが、「三角関数の計算で得られた数値を予め配列変数に格納しておき、キャラクターの座標はその配列変数から順番に取り出していく」という方式です。これにより繰り返しの処理が変数から数値を取り出すだけになったことから、動作の遅延は解消されました。

Pythonでは配列変数とは言わず、「リスト」と呼びますが、今回のソースコードでは、以下の部分が三角関数(コサイン)の計算とリストへの格納になります。
circle_x = [math.cos(math.pi/180*i) for i in range(360)]


他の言語に慣れている人なら、恐らくこんな感じの方が馴染み深いと思います。
for i in range(360):
circle_x[i] = math.cos(math.pi/180*i)


これが一行でまとまる上に見た目も分かりやすいので、 これからも内包表記を多用していこうと思います。

ちなみに、比較的「低速」と言われるPythonですが、当時のX68000のX-BASIC+Cコンパイラーで作成したプログラムよりも断然早く、この程度の円運動なら繰り返し三角関数を計算させる方法でも全く問題ありませんでした(10倍速でも問題無いです)。しかし、今後大きなプログラムを作る時など、端末側に負担をかけない意味で、このやり方は慣れておいた方が良いかなと思っています。

次にスプライト(Sprite)機能です。

また昔話になりますが、上述のX68000のX-BASICや、その数年前のファミコンのプログラミングソフト「ファミリーBASIC」でもスプライト機能に対応していました。スプライト機能を使うとキャラクターを動かしつつ特別な処理をしなくても、背景画像が崩れることはありません。逆にスプライト機能が無いパソコンでは、キャラクターが動作した後に残像が残ってしまうため、その部分のみを都度描き直したり、もしくは画面全体を毎回リフレッシュして描画するなどの手法が必要でした。

ちなみに、昨年作成したHTML+JavaScriptのミニゲームでは、div要素をブロックにして座標を設定する形で、ほぼスプライト機能と同じことができました。

Pygameのスプライトについても、同じような機能を期待していたのですが、残念ながら何らかの処理をしない限り、キャラクターを動かした後に残像が残ってしまいます。そのため、今回作成したサンプルプログラムでは、動作毎に画面をリフレッシュする方式を取っています。

ただ、Pygameのスプライトは衝突(collision)判定が充実していて、グループ化の機能と合わせて使用すれば効率よくプログラムが書けるかも知れません。今回のサンプルプログラムにはその辺りの関数は含めていませんが、また近いうちにスプライト+衝突判定を利用したミニゲームを作ってみようと思います。





Python関連記事(リンク一覧): Python - リスト内包表記とPygameのスプライト機能 / Pythonの学習とPygameを使ったミニアクションゲーム作成 / ...(記事連続表示)

Pythonゲームプログラミング 知っておきたい数学と物理の基本 (Future Coders(NextPublishing)) eBook
Pythonゲームプログラミング 知っておきたい数学と物理の基本 (Future Coders(NextPublishing)) eBookをAmazon.co.jpでチェック


Pythonの学習とPygameを使ったミニアクションゲーム作成

名前: 小川 邦久 リンク: http://kunisan.jp/ 日付: 2017年11月25日

Pythonの学習とPygameを使ったミニアクションゲーム作成ある知人の方より「機械学習(AI)用のプログラミング言語はPythonがメジャー」ということを聞いて、少し前からPythonには興味を持っていました。ただ、40代半ばにもなって、新しいプログラミング言語を学ぶというのは少し抵抗があって、なかなか腰を上げられずにもいました。

私は小学6年~高校2年の間に、PC-6001mkII(NEC)とX68000(シャープ)というパソコンで、BASIC言語を使ってゲームを作ったりしていました。その後、数年のブランクがありましたが、Visual Basic、Excel VBAからプログラミングを再開し、ホームページを自作するようになってからは、Web開発系言語のPerl、JavaScript、PHPも使うようになりました。一方、CやJavaなどのソフトウェア開発系の言語は、今までに全くと言っていい程触れていません。もとからプロのプログラマーではありませんが、週末に時間がある時などに趣味でプログラミングをしている「週末プログラマー」であります(Excel VBAのみ少し仕事で使っています)。ちなみに、PHPを使い始めたのが今から10年前で、それ以降は新しいプログラミング言語には手を出していませんでした。

何だかんだで、今月始めにようやくPythonの入門書を2冊購入し、PCにはPythonパッケージとして人気のあるAnacondaを入れてみました。入門書にあるサンプルプログラムを実際に書いたり書き換えたりしながら、Pythonの基礎を学習していきましたが、「学びやすい言語」という印象を受けました。第一に「読みやすく書きやすい」というのがあり、ユーザー関数やクラスの定義なども他の言語で慣れた人であれば、問題なく使うことができると思います。海外では子供のプログラミング学習でもPythonが使われ始めていると聞いていますが、これも頷けます。子供やプログラミング初心者から、大学の研究、人工知能、アプリの開発などまで幅広く使われており、さらに私のような中年が新たに学び始めるのにもPythonの壁は低いと感じます。

ただ、プログラミング言語を学ぶ上では、本を読んだりサンプルプログラムを少し動かしただけでは、使い方を理解しきれません。自分なりの使い方を確立していくステップとして、まずはミニアクションゲームを作成することにしました。ゲーム制作用のモジュールとしてPygameも利用します。

ということで、「DOG & BURGERS」というミニアクションゲームが完成しました。先週末から作り始めたので、製作期間は約1週間です。なぜ「犬」と「ハンバーガー」なのかというと、手持ちの画像素材集の犬とハンバーガーの画像が目についたので、そのままこれを使ってゲームにした、という流れです。以下、ゲームの動画になります。



プログラムはこんな感じです。


ファイル一式はこちらからダウンロードできます
※本プログラムやファイルの二次配布や二次掲載はご遠慮ください。個人的なプログラム改造はご自由にどうぞ。ただし、本プログラムに関するご質問等はお受けしません。

今回のミニゲームではPythonのユーザー関数やクラスの定義の他、Pygameによるキー入力、画像ファイルの表示、音の再生などを試すことができました。ここ最近では一年前にJavaScriptでミニゲームをいくつか作りましたが、ほぼ同じようなレベルのものがPythonでも作れそうです。ただ、「DOG & BURGERS」では以下の問題があり、今のところ解決せずにそのまま放置しています(他のPCでは確認していないので、私のPCだけの問題の可能性もあります)。

・効果音の遅延。0.3秒程ズレが出てしまいます。
・キー入力がやや不安定。カーソルキーやスペースキーを押しているのに、たまに反応しないことがあります。

今回はPython学習の第一歩という位置づけですが、次はWebサーバー上で動く何らかのプログラムを作ってみようと思います。WebArenaのSuiteXでもPython対応ということなので(ただし、バージョンは2.7)、せっかくなのでこれを使って色々と動かしてみます。



Python関連記事(リンク一覧): Python - リスト内包表記とPygameのスプライト機能 / Pythonの学習とPygameを使ったミニアクションゲーム作成 / ...(記事連続表示)

みんなのPython 第4版
みんなのPython 第4版をAmazon.co.jpでチェック


| 前ページ(新しい記事) |     | 次ページ(過去の記事) |