pygameでゲームのプロトタイプを
なんか急にコードどうでもよいプログラミングがしたくなったのでむかつくアイコンぶっ飛ばすゲーム作った.
ヒットストップするようにしたので,当たった感あると思う.
たったコレだけでジョイスティックも対応したゲーム作れるしとてもよいと思う.
ネイティブな言語で書くのは面倒なので,こういうのでプロトタイピングしてから書くと非常に良いと思う.
#!/usr/bin/env python #-*- coding:utf-8 -*- import pygame import pygame.locals from pygame.locals import Rect import random import math import sys SCREEN_SIZE = (640, 480) BACKGROUND = (0x7f, 0x7f, 0x7f) class Controller: x = 0 y = 0 a = 0 b = 0 buttons = [False for i in range(16)] con = Controller() hitEffect = False class Atack: def __init__(self, rect, direc, damage): self.rect = rect self.direc = direc self.damage = damage class Player: vx, vy = 0.0, 0.0 direc = 4 secondJumpFlg = True x = SCREEN_SIZE[0] / 2 y = SCREEN_SIZE[1] / 2 hit = None gauge = 0 def __init__(self, screen): self.screen = screen def update(self): atack = 0 jump = 1 smash = 2 if not con.buttons[atack]: if con.x > 0.0: self.vx = min(self.vx + con.x * con.x * con.x * 2.5, con.x * 20.0) self.direc = 4 elif con.x < 0.0: self.vx = max(self.vx + con.x * con.x * con.x * 2.5, con.x * 20.0) self.direc = -4 if con.buttons[jump]: if self.y == SCREEN_SIZE[1] - 16 - 32: self.vy -= 12.0 self.secondJumpFlg = False elif self.vy > -2.5 and not self.secondJumpFlg: self.vy -= 12.0 + self.vy self.secondJumpFlg = True self.vx *= 0.925 self.vy = min(self.vy + 0.5, 5.0) self.x = min(SCREEN_SIZE[0], max(0, self.x + self.vx)) if self.x == SCREEN_SIZE[0] or self.x == 0 and self.y > 0.0: self.vy = min(self.vy + 0.15, 2.5) else: self.vy += 0.0125 if con.y > 0: self.vy += con.y self.y = min(SCREEN_SIZE[1] - 16 - 32, self.vy + self.y) if self.y == SCREEN_SIZE[1] - 16 - 32: self.vy = 0.0 self.hit = None if con.buttons[atack]: if con.y < -0.5: hitRect = (int(self.x) - 24, int(self.y) - 48, 48, 24) elif con.y > 0.5: hitRect = (int(self.x) - 32, int(self.y) + 8, 64, 16) elif self.direc > 0: hitRect = (int(self.x) + self.direc, int(self.y) - 8, 48, 24) elif self.direc < 0: hitRect = (int(self.x) + self.direc - 48, int(self.y) - 8, 48, 24) pygame.draw.ellipse(self.screen, (255, 0, 255), hitRect) self.hit = Atack(hitRect, (con.x * 10, min(con.y, -0.5) * 7.5), 1) elif con.buttons[smash] and self.gauge >= 80: if con.y < -0.5: hitRect = (int(self.x) - 24, int(self.y) - 48, 48, 24) elif con.y > 0.5: hitRect = (int(self.x) - 32, int(self.y) + 8, 64, 16) elif self.direc > 0: hitRect = (int(self.x) + self.direc, int(self.y) - 8, 48, 24) elif self.direc < 0: hitRect = (int(self.x) + self.direc - 48, int(self.y) - 8, 48, 24) pygame.draw.ellipse(self.screen, (255, 255, 0), hitRect) self.hit = Atack(hitRect, (con.x * 100, min(con.y - 0.5, -0.4) * 100), 10) self.gauge -= 80 self.screen.fill*1 pygame.draw.circle(self.screen, (255, 255, 255), (int(self.x) + self.direc, int(self.y) - 20), 2) class Enemy: vx, vy = 0.0, 0.0 damage = 0 def __init__(self, screen, x, y=SCREEN_SIZE[1]/2): self.screen = screen self.x = x self.y = y self.direc = random.choice*2 def update(self, player): global hitEffect if abs(self.vx) < 0.5: self.vx += self.direc / abs(self.direc) * 0.5 self.vx *= 0.925 self.vy = min(self.vy + 0.5, 5.0) self.x = min(SCREEN_SIZE[0], max(0, self.x + self.vx)) self.y = max(-640, min(SCREEN_SIZE[1] - 16 - 16, self.vy + self.y)) if self.y == -640: self.vy *= -1 if self.x == SCREEN_SIZE[0] or self.x == 0: self.vx *= -1 self.direc *= -1 if self.y == SCREEN_SIZE[1] - 16 - 16: self.vy = 0.0 pygame.draw.rect(self.screen, (0x40, 0x40, 0x40), Rect(self.x - 16, self.y - 16, 32, 32), 3) pygame.draw.circle(self.screen, (0x40, 0x40, 0x40), (int(self.x) + self.direc + 4, int(self.y) - 8), 4, 4) pygame.draw.circle(self.screen, (0x40, 0x40, 0x40), (int(self.x) + self.direc - 4, int(self.y) - 8), 4, 4) if player.hit: hitRect = player.hit.rect r = Rect(self.x - 16, self.y - 16, 32, 32) if r.colliderect(hitRect): dx = player.hit.direc[0] + (self.x - player.x) / max(0.01, abs(player.x - self.x)) dy = min(-1.0, player.hit.direc[1]) self.vx += dx * self.damage ** 0.5 / 10 self.vy += dy * self.damage ** 0.5 / 10 if math.hypot(self.vx, self.vy) > 32.0: hitEffect = True else: hitEffect = False self.damage += player.hit.damage player.gauge += player.hit.damage class Test: def __init__(self, screen): self.screen = screen self.player = Player(screen) self.another = Player(screen) self.enemy = [Enemy(screen, random.randint(32, SCREEN_SIZE[1] - 32)) for i in range(16)] def update(self): pygame.draw.line(self.screen, (0, 0, 0), (0, SCREEN_SIZE[1] - 16), (SCREEN_SIZE[0], SCREEN_SIZE[1] - 16)) self.player.update() for e in self.enemy: e.update(self.player) self.screen.fill*3 return self class Title: def __init__(self, screen): self.screen = screen def update(self): if con.x > 0: self.screen.fill*4 else: self.screen.fill*5 if con.a > 0: self.screen.fill*6 else: self.screen.fill*7 if con.y > 0: self.screen.fill*8 else: self.screen.fill*9 if con.b > 0: self.screen.fill*10 else: self.screen.fill*11 for x in range(16): pygame.draw.rect(self.screen, (0, 0, 255), Rect(50 + 15 * x, 50, 10, 10), 1 if con.buttons[x] else 0) if con.buttons[0]: return Test(self.screen) return self def main(): global hitEffect pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE) pygame.display.set_caption("testgame") pygame.joystick.init() try: joystick = pygame.joystick.Joystick(0) # create a joystick instance joystick.init() # init instance print 'Joystickの名称: ' + joystick.get_name() print 'ボタン数 : ' + str(joystick.get_numbuttons()) except pygame.error: print 'Joystickが見つかりませんでした。' joystick = None currentScene = Title(screen) while True: if joystick: for event in pygame.event.get(): if event.type == pygame.locals.QUIT: return 0 elif event.type == pygame.locals.JOYAXISMOTION: con.x = joystick.get_axis(0) con.y = joystick.get_axis(1) con.a = joystick.get_axis(4) con.b = joystick.get_axis(3) elif event.type == pygame.locals.JOYBUTTONDOWN: con.buttons[event.button] = True elif event.type == pygame.locals.JOYBUTTONUP: con.buttons[event.button] = False else: pressed_keys = pygame.key.get_pressed() con.x = 0.0 con.y = 0.0 if pressed_keys[pygame.locals.K_LEFT]: con.x = -1.0 if pressed_keys[pygame.locals.K_RIGHT]: con.x = 1.0 if pressed_keys[pygame.locals.K_UP]: con.y = -1.0 if pressed_keys[pygame.locals.K_DOWN]: con.y = 1.0 for i, v in enumerate([pygame.locals.K_z, pygame.locals.K_x, pygame.locals.K_c, pygame.locals.K_v]): con.buttons[i] = pressed_keys[v] for event in pygame.event.get(): if event.type == pygame.locals.QUIT: return 0 screen.fill(BACKGROUND) next = currentScene.update() if next != currentScene: currentScene = next pygame.display.flip() if hitEffect: hitEffect = False pygame.time.wait(200) pygame.time.wait(15) return 0 if __name__ == '__main__': sys.exit(main())
ヒットストップするようにしたので,当たった感あると思う.
たったコレだけでジョイスティックも対応したゲーム作れるしとてもよいと思う.
ネイティブな言語で書くのは面倒なので,こういうのでプロトタイピングしてから書くと非常に良いと思う.
*1:0, 0, 0), Rect(self.x - 8, self.y - 32, 16, 64
*2:4, -4
*3:0, 0, 255), Rect(0, 10, self.player.gauge, 20
*4:255, 0, 0), Rect(300, 10, 100 * con.x, 20
*5:255, 0, 0), Rect(300 + 100 * con.x, 10, - 100 * con.x, 20
*6:127, 0, 0), Rect(300, 30, 100 * con.a, 20
*7:127, 0, 0), Rect(300 + 100 * con.a, 30, - 100 * con.a, 20
*8:0, 255, 0), Rect(10, 300, 20, 100 * con.y
*9:0, 255, 0), Rect(10, 300 + 100 * con.y, 20, - 100 * con.y
*10:0, 127, 0), Rect(30, 300, 20, 100 * con.b
*11:0, 127, 0), Rect(30, 300 + 100 * con.b, 20, - 100 * con.b