Python第07周:一个小游戏

本篇严重参考Julian Meyer发表的文章:Beginning Game Programming for Teens with Python

本次作业将创建一个简单的游戏叫做英雄兔ver0.1版;

游戏背景:

在这里作为英雄的兔子要保卫城堡,它必须能够移动和射击反击敌人
(关于敌人我们在后续章再添加,那时你已经能看懂大部分代码了)。

# 设计步骤

# 第一步:Hello Bunny(嘿,兔子)
# 第二步:添加布景
# 第三步:让兔子动起来
# 第四步: 旋转兔子
# 第五步:射击吧,兔子!
# V0.1 Over!

# 第一步:(编写简单的)Hello Bunny(嘿,兔子)

# 1 - 导入PyGame库
import pygame
from pygame.locals import * #导入命名空间
 
# 2 - 初始化PyGame并设置显示窗口
pygame.init()
width, height = 640, 480
screen=pygame.display.set_mode((width, height))
 
# 3 - 加载你想要给bunny使用的图片
player = pygame.image.load("resources/images/dude.png")
 
# 4 - 循环执行以下缩进的代码
while 1:
    # 5 - 每次绘图前,将屏幕填充成黑色
    screen.fill(0)
    # 6 - 以100*100的大小显示图片
    screen.blit(player, (100,100))
    # 7 - 更新屏幕
    pygame.display.flip()
    # 8 - 检查是否有新事件
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            pygame.quit()
            exit(0)

把它保存到你的游戏目录下(即资源子目录)并命名为itgame.py。让我们逐段分析以上代码:
1. 导入PyGame库。这一步让你在你的程序中使用来自库中的函数。
2. 初始化PyGame并设置显示窗口。
3. 加载你想要给bunny使用的图片。
4. 循环执行以下缩进的代码。
5. 在绘图前,将屏幕填充成黑色。
6. 将之前加载进来的bunny图片以100*100的大小显示在屏幕上。
7. 更新屏幕。
8. 检查是否有新事件,如果有的话,否则转到退出命令,退出程序。
注意:根据PyGame的文档,你不需要调用pygame.quit()因为解析器关闭时会自动调用它。
如果现在运行这段代码(在Idle菜单栏点击 “Run\Run Module"),你应该可以看到一个如下所示的屏幕:
 
耶,兔子就显示在屏幕上了,并准备做动作!
但是只有一只兔子显示在一个黑漆漆的屏幕上,这个游戏看起来很吓人且很孤单。接下来要做的就是稍微美化一下咯。

# 第二步:添加布景

我们首先给游戏场景添加背景图片,可以通过调用一组screen.blit()来完成背景添加。
在代码的#3 小节,载入角色图像之后添加下面的代码
# 3 - 加载你想要给bunny使用的图片
player = pygame.image.load("resources/images/dude.png")
grass = pygame.image.load("resources/images/grass.png")
castle = pygame.image.load("resources/images/castle.png")
这些代码载入图片然后赋给指定的变量,然后把它们画到屏幕上。但如果你检查草地的图片,你会发现它没有覆盖整个640 x 480的屏幕,所以你必须平铺使草地的图片完全覆盖屏幕。
在#6小节的开始(把兔子画在屏幕上之前),添加以下代码到game.py:
    # 6 - 以100*100的大小显示图片
    for x in range(width/grass.get_width()+1):
        for y in range(height/grass.get_height()+1):
    screen.blit(grass,(x*100,y*100))
    screen.blit(castle,(0,30))
    screen.blit(castle,(0,135))
    screen.blit(castle,(0,240))
    screen.blit(castle,(0,345 ))
    screen.blit(player, (100,100))

正如你所见,首先把x坐标通过for循环递增,在这个循环中再把y坐标循环递增,并且将草地画在使用循环生成的x、y坐标上。紧接着的一组代码只是将城堡画在屏幕上。从现在开始,变得好看点了!
你现在运行这个程序,你会看到像如下的结果:

# 第三步:让兔子动起来

下面需要添加一些真正的游戏元素,比如让兔子响应键盘的按键。
要做到这一点,需要一个方法记录哪一个键在某一时刻被按下。
可以简单的使用一个数组保存在游戏需要使用的键的按下状态。
添加如下代码到game.py的#2小节结束(在你设了屏幕高和宽度之后) :
# 2 - 初始化PyGame并设置显示窗口
...
screen=pygame.display.set_mode((width, height))
keys = [False, False, False, False]
playerpos=[100,100] #游戏角色的位置

这段代码是非常明了。数组keys按WASD的顺序记录它们的状态。
数组的每个元素对应一个键,第一个是上W,下S,左A右D。
playerpos变量定义程序开始绘制游戏角色的起始位置。因为这个游戏将移动游戏角色到不同的位置,设置一个储存角色位置的变量,然后便可以简单地将角色绘制到这个位置。
现在你需要修改现有的代码来绘制角色,使用新的playerpos变量,将# 6的程序:
screen.blit(player, (100,100))
改为:
screen.blit(player, playerpos)
接下来,基于哪些按键被按下更新键数组,PyGame通过添加event.key事件使检测按键很容易实现。
在# 8检测event.type==pygame.QUIT之后,添加这些代码
(如果有块缩进的话使用与pygame.QUIT相同的缩进级):
    # 8 - 循环游戏、检查是否有新事件

if event.type == pygame.KEYDOWN:
            if event.key == K_w:
                keys[0] = True
            elif event.key == K_a:
                keys[1] = True
            elif event.key == K_s:
                keys[2] = True
            elif event.key == K_d:
                keys[3] = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_w:
                keys[0] = False
            elif event.key == pygame.K_a:
                keys[1] = False
            elif event.key == pygame.K_s:
                keys[2] = False
            elif event.key == pygame.K_d:
                keys[3] = False
哇!这里有很多行代码,如果你把它按If语句拆分也不是很复杂的。
首先你要检测一是否有键被按下或释放,然后你需要检测哪个键被按下或者释放,如果被按下或者释放的键是你要使用的键,根据键值更新相应的键变量。
最后,你需要更新playerpos变量作为键按下的响应,这太简单了。
将下附代码添加到game.py的末尾(使用和for循环相同的缩进级)
    # 9 - Move player
    if keys[0]:
        playerpos[1] -= 5
    elif keys[2]:
        playerpos[1] += 5
    if keys[1]:
        playerpos[0] -= 5
    elif keys[3]:
        playerpos[0] += 5
这段代码只是检查哪个键被按下,然后添加或减去游戏角色的x或y位置(取决于按下的键)来移动游戏角色。

# 第四步: 旋转兔子

是的,你的兔子现在可以随着你的按键移动,但用鼠标来旋转兔子朝向到你选择的方向岂不更酷,所以它不是所有时间都朝向一个方向。使用三角函数来实现:
应用atan2三角函数获得旋转角度(z)。记住,Z值是弧度。
atan2函数在Python的math库总,所有先在#1结尾处增加:
import math

然后,将#6最后一行(screen.blit...这行)替换成下面的代码:
# 6.1 - Set player position and rotation
position = pygame.mouse.get_pos()
angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+26))
playerrot = pygame.transform.rotate(player, 360-angle*57.29)
playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2)
screen.blit(playerrot, playerpos1)

让我们梳理一下上面代码的基本流程。首先获取鼠标和游戏角色的位置,然后你对两个位置应用atan2函数,之后,你将atan2返回的弧度转化成度数(将弧度乘以近似57.29或360/2π)。
因为兔子会旋转,它的位置也将会改变。所以现在计算兔子的新位置并把它显示在屏幕。
再次运行这个游戏。如果你只按了“WASD”键,那么这个游戏应该和之前完全一样,但如果你移动你的鼠标兔子也会随之旋转!

# 第五步:射击吧,兔子!

现在你的兔子已经可以自由活动了,是时候给它添加更多的动作了。让兔子可以用弓箭射击敌人!
这一步稍微有点复杂,因为你必须记录所有射出的剑,更新它们的位置、旋转并且在它们飞出屏幕后删除它们。
首先,在初始化小节(#2小节)的结束添加必要的变量:
acc=[0,0] #记录玩家的射击精度
arrows=[] # 记录所有的箭

精度变量acc实际上是一个包含射击数量和命中獾次数的列表。
最后我们可以使用这些信息来计算精度的百分比。
接下来,在section #3的末尾加载弓箭图像:
arrow = pygame.image.load("resources/images/bullet.png")

现在当玩家点击鼠标,弓箭就要射出。
在section #8的末尾加入以下代码作为新的事件句柄
if event.type == pygame.MOUSEBUTTONDOWN:
            position = pygame.mouse.get_pos()
            acc[1] += 1   
            arrows.append(
                [math.atan2(position[1] - (playerpos1[1] + 32), position[0] - (playerpos1[0] + 26)), playerpos1[0] + 32,
                 playerpos1[1] + 32])

这些代码检查是否有鼠标点击,如果有它会读取鼠标位置,并根据玩家的旋转和指针的位置计算出弓箭的旋转。这个旋转储存在arrows数组里。
接下来你需要真正在屏幕上画出弓箭了。在section #6.1之后插入以下代码:
# 6.2 - Draw arrows
for bullet in arrows:
    index=0
    velx=math.cos(bullet[0])*10
    vely=math.sin(bullet[0])*10
    bullet[1]+=velx
    bullet[2]+=vely
    if bullet[1]<-64 or bullet[1]>640 or bullet[2]<-64 or bullet[2]>480:
        arrows.pop(index)
    index+=1
    for projectile in arrows:
        arrow1 = pygame.transform.rotate(arrow, 360-projectile[0]*57.29)
        screen.blit(arrow1, (projectile[1], projectile[2]))
运用基本的三角函数可以计算出vely和velx。10是弓箭的速度。if语句检查弓箭是否飞出边界,如果是则删除该弓箭。第二个for语句循环过arrows数组并画出相应旋转的弓箭。
试试运行程序。你应该有一只兔兔在你点击鼠标时发射弓箭了。

祝你好运!

时间: 2024-11-05 22:28:34

Python第07周:一个小游戏的相关文章

python写的battle ship小游戏 - 1.0

最近学python,这是今天写的一个小游戏. from random import randint class Board(object): board = [] def __init__(self,row,col): self.board = [] self.row = row self.col = col for i in range(row): self.board.append( ["O"] * col ) def print_board(self): space = (sel

DirectX游戏开发——从一个小游戏开始

本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/26364129 写在前面:自己对DirectX挺感兴趣的,加上自己目前在研究3D重建方面的东西,所以利用课余时间学习一下.看了一段时间的书,感觉还是靠动手编写一些小例子来学习,进步的更快体会的更深.所以从我自己写的一个小游戏开始吧,把自己学习心得和自己的一些想法写下来.更是欢迎有兴趣的童鞋来和我交流. 首先:先把我的小例子分享

微信为什么要搞一个小游戏?

众厂关于 H5 游戏市场的争夺,自 2014 年以来,一直就没有停止过.但一直也没有尘埃落定,最终花落谁家,鹿死谁手现在还不好讲.微信推出小程序,继而推出小游戏,只是腾讯数年来在 H5 市场企业战略的一环. 微信为什么要自定义一套技术,起名为小程序?明明就是原来的 H5 技术,为什么 CSS 不叫 CSS,叫 WXSS:为什么 HTML 不叫 HTML,叫 WXML:为什么明明有 JS.TS,还要自主研发一个 WXS,并且声称"WXS 与 JS 是不同的语言,有自己的语法,并不和 JS 一致&q

用Python写一个小游戏

刚学Python时间不长,但也知道了一点,看别人的参考写了一个猜数字小游戏,也算是禹学于乐吧. #!/usr/bin/env   python #coding=utf-8 import random secret = random.randint(1,100) guess,tries = 0,0 print u"已经给出了一个1-99的数字" while guess != secret and tries < 5: print u"请给出你猜的数字:" pri

通过一个小游戏开始接触Python!

之前就一直嚷嚷着要找视频看学习Python,可是一直拖到今晚才开始....好好加油吧骚年,坚持不一定就能有好的结果,但是不坚持就一定是不好的!! 看着视频学习1: 首先,打开IDLE,在IDLE中新建new file  输入一下代码: print("-----------------------我爱Python-------------------") temp = input("不妨猜一下我现在心里想的是哪个数字:") guess = int(temp) if g

Python编写微信打飞机小游戏(四)

之前的工作已经基本上将我方飞机的图形显示工作做的差不多了,这篇博客中我们将开始添加敌方飞机——小型敌机.中型敌机(直升机)和大型敌机(坦克).新建一个enemy.py文件,导入pygame和random模块,开始编写吧(还是要注意文件编码问题,以后就不再啰嗦了). 敌方飞机类与我方飞机模块有一定的相似性,但不会左右移动,不会发射子弹等等.小型敌机是敌方飞机中最基本的类型,一击毙命,没有血量.没有出场音效.中型敌机有一定血量,损毁时附带特殊音效.大型敌机血量最多,出场和损毁时都有特殊音效,游戏中中

Python编写微信打飞机小游戏(一)

最近开始学习Python语言,发现Python有一个神奇的Pygame模块,在编写小游戏时显得非常方便,于是参照教学视频编写了一个微信打飞机的小游戏,网上有很多相关的博客,但都不是很详细,大都是直接贴代码,于是决定沉下心来把编写程序的过程记录下来,与大家分享. 首先声明一点,这篇博客完全参照了小甲鱼的<零基础入门学习Python>教学视频,为了尊重原创,特将原作者的视频地址公布如下:<零基础入门学习Python> Python编译器和Pygame模块的安装网上的教程很多,这里不再赘

使用Cocos2d-X实现一个小游戏PhotoExhibition

最近也不知道怎么了,总想用Cocos2d-X做一个比较好的东西,想想也是,学习Cocos2d-X快一个月了,也该做个东西练练手了,最近总用手机拍照,看照片,忽然想做一款与图片相关的小游戏,游戏非常简单打开后会显示一个界面,界面上有三个按钮(实际上是使用精灵创建的菜单项) 点击按钮后可以进入相关的场景中(例如点击校园后进入校园创建) 通过鼠标的拖拽可以查看校园场景的图片 如果再看其它创建的图片可以通过点击右下角返回程序主界面 工程文件结构 文件解析: MenuScene.h/MenuScene.c

Python编写微信打飞机小游戏(十一)

在这篇博文中,我们准备为打飞机小游戏添加一个暂停的功能,即用户在游戏过程中随时可以通过单击屏幕右上方的一个暂停按钮来暂停和恢复游戏.这个功能看似比较简单,但其中涉及了鼠标操作.图片切换.代码结构的重置等等,接下来我们一一进行介绍. 1.加载暂停按钮图标 在image文件夹下一共有四张暂停按钮的图片,分别为深色和浅色两组,首先在main()函数中加载相关图片资源并初始化暂停/开始标志位: paused = False # 标志是否暂停游戏 pause_nor_image = pygame.imag

做了一个小游戏,结项目,数数坑

这是一个微信端的,投篮小游戏. 游戏规则如下: 点击开始,进入游戏,按住右下角红色按钮控制投篮力度,3次进球以后游戏难度将会升级.45秒内您的进球数将会计入排行榜,最终排行榜上的名次可以获得相应奖励,快来投篮冲榜领福利吧. 一.动画效果 做微信项目,相信大家和我一样,已经习惯了放弃使用jQuery,转而使用zepto.但是zepto并没有集成animate()方法.因此若想使用动画,用不想做兼容处理,最高效的方法是重拾jQuery. $(selector).animate(styles,spee