之前看了一個項目,覺得還挺有意思的,是關於做一個像素風的游戲,現在,虛幻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()
還比較好玩,大家可以嘗試下。