之前看了一个项目,觉得还挺有意思的,是关于做一个像素风的游戏,现在,虚幻4,u3d,已经让游戏愈发的好看,好玩,曾经我们童年的像素风游戏,愈来愈少。所以,这里我们就回味下。
Pyxel是一个python的经典像素风游戏制作引擎。
由于像素风游戏的机制非常简单(如:最多只能显示16种颜色、播放4种声音等),现在你也可以轻松地享受这种游戏的制作过程。
Windows
安装Python3(3.7或更高版本)之后,输入以下pip
命令来安装Pyxel:
pip install -U pyxel
在python代码导入Pyxel模块后,首先用init
函数指定窗口大小,然后用run
函数启动Pyxel应用。
import pyxel pyxel.init(160, 120) def update(): if pyxel.btnp(pyxel.KEY_Q): pyxel.quit() def draw(): pyxel.cls(0) pyxel.rect(10, 10, 20, 20, 11) pyxel.run(update, draw)
run
函数的两个参数update
函数和draw
函数分别用来在需要时更新帧和绘制画面。
实际应用中,建议将pyxel代码封装成如下类:
import pyxel class App: def __init__(self): pyxel.init(160, 120) self.x = 0 pyxel.run(self.update, self.draw) def update(self): self.x = (self.x + 1) % pyxel.width def draw(self): pyxel.cls(0) pyxel.rect(self.x, 0, 8, 8, 9) App()
有时也可简单使用show
和flip
画出简单的画面和动画。
show
函数可以显示画面直到ESC
键按下。
import pyxel pyxel.init(120, 120) pyxel.cls(1) pyxel.circb(60, 60, 40, 7) pyxel.show() #flip函数可以更新一次画面。 import pyxel pyxel.init(120, 80) while True: pyxel.cls(3) pyxel.rectb(pyxel.frame_count % 160 - 40, 20, 40, 40, 7) pyxel.flip()
像素风的游戏比较容易制作,关键的逻辑还需要程序员自己去发掘。
下面是一个例子:
from random import randint import pyxel import gzip class App: def __init__(self): pyxel.init(160, 120, caption="Pyxel Jump") #pyxel.load("jump_game.pyxres") self.score = 0 self.player_x = 72 self.player_y = -16 self.player_vy = 0 self.player_is_alive = True self.far_cloud = [(-10, 75), (40, 65), (90, 60)] self.near_cloud = [(10, 25), (70, 35), (120, 15)] self.floor = [(i * 60, randint(8, 104), True) for i in range(4)] self.fruit = [(i * 60, randint(0, 104), randint(0, 2), True) for i in range(4)] pyxel.playm(0, loop=True) pyxel.run(self.update, self.draw) def update(self): if pyxel.btnp(pyxel.KEY_Q): pyxel.quit() self.update_player() for i, v in enumerate(self.floor): self.floor[i] = self.update_floor(*v) for i, v in enumerate(self.fruit): self.fruit[i] = self.update_fruit(*v) def update_player(self): if pyxel.btn(pyxel.KEY_LEFT) or pyxel.btn(pyxel.GAMEPAD_1_LEFT): self.player_x = max(self.player_x - 2, 0) if pyxel.btn(pyxel.KEY_RIGHT) or pyxel.btn(pyxel.GAMEPAD_1_RIGHT): self.player_x = min(self.player_x + 2, pyxel.width - 16) self.player_y += self.player_vy self.player_vy = min(self.player_vy + 1, 8) if self.player_y > pyxel.height: if self.player_is_alive: self.player_is_alive = False pyxel.play(3, 5) if self.player_y > 600: self.score = 0 self.player_x = 72 self.player_y = -16 self.player_vy = 0 self.player_is_alive = True def update_floor(self, x, y, is_active): if is_active: if ( self.player_x + 16 >= x and self.player_x <= x + 40 and self.player_y + 16 >= y and self.player_y <= y + 8 and self.player_vy > 0 ): is_active = False self.score += 10 self.player_vy = -12 pyxel.play(3, 3) else: y += 6 x -= 4 if x < -40: x += 240 y = randint(8, 104) is_active = True return x, y, is_active def update_fruit(self, x, y, kind, is_active): if is_active and abs(x - self.player_x) < 12 and abs(y - self.player_y) < 12: is_active = False self.score += (kind + 1) * 100 self.player_vy = min(self.player_vy, -8) pyxel.play(3, 4) x -= 2 if x < -40: x += 240 y = randint(0, 104) kind = randint(0, 2) is_active = True return (x, y, kind, is_active) def draw(self): pyxel.cls(12) # draw sky pyxel.blt(0, 88, 0, 0, 88, 160, 32) # draw mountain pyxel.blt(0, 88, 0, 0, 64, 160, 24, 12) # draw forest offset = pyxel.frame_count % 160 for i in range(2): pyxel.blt(i * 160 - offset, 104, 0, 0, 48, 160, 16, 12) # draw clouds offset = (pyxel.frame_count // 16) % 160 for i in range(2): for x, y in self.far_cloud: pyxel.blt(x + i * 160 - offset, y, 0, 64, 32, 32, 8, 12) offset = (pyxel.frame_count // 8) % 160 for i in range(2): for x, y in self.near_cloud: pyxel.blt(x + i * 160 - offset, y, 0, 0, 32, 56, 8, 12) # draw floors for x, y, is_active in self.floor: pyxel.blt(x, y, 0, 0, 16, 40, 8, 12) # draw fruits for x, y, kind, is_active in self.fruit: if is_active: pyxel.blt(x, y, 0, 32 + kind * 16, 0, 16, 16, 12) # draw player pyxel.blt( self.player_x, self.player_y, 0, 16 if self.player_vy > 0 else 0, 0, 16, 16, 12, ) # draw score s = "SCORE {:>4}".format(self.score) pyxel.text(5, 4, s, 1) pyxel.text(4, 4, s, 7) App()
还比较好玩,大家可以尝试下。