プログラミング言語「Python」で制作 Part80 | Photoshop CC Tutorials

今回はプログラミング言語の「Python」を使って作成しました。

 

下記の本のサンプルの書き方だと自分の環境では滑らかにブロックを掴むことができなかったので「ブロックを掴んでブロックを置く処理」は自作しました。

 

■ プログラム

from game import *
from crash import *
import math
import random

image_player = [image('penguin_left.png'), image('penguin_right.png')]
image_block = image('block.png')

SW, SH = 1, 9/16
gravity = 0.001


def hit_block(m):
    for b in group(block):
        dx, dy = m.x-b.x, m.y-b.y
        ax, ay = abs(dx), abs(dy)
        sx, sy = m.sx+b.sx, m.sy+b.sy
        if m != b and b.state == 0 and ax < sx and ay < sy:
            if ax < b.sx and ay < b.sy:
                new_crash(m.x, m.y, 0.01, 20, 0.98)
                m.life = 0
            if ay < sy*0.6:
                m.vx = 0
                m.x = b.x+math.copysign(sx, dx)
            if ax < sx*0.8:
                m.vy = 0
                m.y = b.y+math.copysign(sy, dy)

def get_block(x, y):
    for b in group(block):
        dx, dy = x-b.x, y-b.y
        ax, ay = abs(dx), abs(dy)
        if ax < b.sx and ay < b.sy:
            return b

zKeyOldDownCount = 0
STATE = 0
def player(p):
    global zKeyOldDownCount, STATE

    p.vx = 0
    #----------------------------------------------------------
    # キーイベント 左
    #----------------------------------------------------------
    if key(LEFT):
        p.vx, p.ox = -0.01, -1
        p.image = image_player[0]
    #----------------------------------------------------------
    # キーイベント 右
    #----------------------------------------------------------
    if key(RIGHT):
        p.vx, p.ox = 0.01, 1
        p.image = image_player[1]
    x0, y0 = p.x+p.ox*p.sx*1.1, p.y-p.sy*0.9
    x1, y1 = p.x+p.ox*p.sx*1.3, p.y+p.sy*1.1
    #----------------------------------------------------------
    # キーイベント 上
    #----------------------------------------------------------
    if key(UP) and get_block(x0, y0) and not get_block(x1, y1):
        p.vy = 0.01
    else:
        p.vy -= gravity
    p.x += p.vx
    p.y += p.vy
    hit_block(p)
    if abs(p.x) > SW+p.sx or abs(p.y) > SH+p.sy:
        new_crash(p.x, p.y, 0.01, 20, 0.98)
        p.life = 0

    if key(Z) == True:
        zKeyOldDownCount += 1
    elif key(Z) == False:
        zKeyOldDownCount = 0

    if p.state == 0:
        #----------------------------------------------------------
        # キーイベント Z ブロック掴む
        #----------------------------------------------------------
        #if not key_old(Z) and key(Z):
        if zKeyOldDownCount == 1 and key(Z) and STATE == 0:
            b = get_block(p.x+p.ox*p.sx*1.1, p.y)

            # ブロックと接触
            if b:
                STATE = 1
                p.block = b
                p.state = b.state = 1
        #----------------------------------------------------------
        # キーイベント Z ブロック掴んで運ぶ
        #----------------------------------------------------------
    elif p.state == 1 and STATE == 1:
        b = p.block
        b.x, b.y = p.x, p.y+p.sy+b.sy
        x, y = p.x+p.ox*p.sx*2, p.y+p.sy*2
        #----------------------------------------------------------
        # キーイベント Z ブロック離す
        #----------------------------------------------------------
        if key(Z) and not get_block(x, y) and zKeyOldDownCount == 1:
            STATE = 0
            b.x, b.y = x, y
            b.vx = b.vy = 0
            p.state = b.state = 0
            p.block = None
        #----------------------------------------------------------
        # キーイベント X
        #----------------------------------------------------------
        if not key_old(X) and key(X) and not get_block(x, y):
            b.x, b.y = x, y
            b.vx, b.vy = p.ox*0.03, 0.02
            p.state = b.state = 0
            STATE = 0
            p.block = None
    if random.random() < 0.04:
        add(block, image_block, 0.05, random.uniform(-1, 1), SH+0.05)
    score(len(list(group(block)))-score())

def block(b):
    if b.state == 0:
        b.vx *= 0.95
        b.vy -= gravity
        b.x += b.vx
        if b.y > -SH+b.sy:
            b.y += b.vy
        else:
            b.y -= 0.0000
        hit_block(b)
        if abs(b.x) > SW+b.sx or abs(b.y) > SH+b.sy:
            b.life = 0

def start():
    global STATE

    STATE = 0
    score()
    add(player, image_player[0], 0.05, 0, -0.3, ox=-1)
    for i in range(-2, 3):
        add(block, image_block, 0.05, i*0.1, -0.4)
    add(block, image_block, 0.05, 0.2, -0.3)
    add(block, image_block, 0.05, -0.2, -0.3)

run(start, 1280, 720)

 

■ 参考書

「Pythonでつくる ゲームプログラミング入門」

 

■ ゲーム用ライブラリ

「pyglet」

 

■ プログラミング言語

「Python」