1.安装pygame
2.想想我要写点什么……
参考:
one:
我其实超级想用用王者荣耀的东西的,趁机熟悉熟悉王者世界观什么的,百度查到一个用LOL地图的
two:
three:
这个博客里面有一大堆,我觉得有的思路真的很难
还有这个(应该是一样的就是这个可能是总结好的)
four:
five:
3.我有一点点想写一个双人对战的游戏,就用王者的角色
参考点:
这个可能比较详细:http://blog.jobbole.com/46308/
英文的:https://www.raywenderlich.com/2795-beginning-game-programming-for-teens-with-python
4.确定好辽,写一个塔防游戏,就模仿那个兔子
#妲己:512*528
#娜可露露:256*256
#蓝方防御塔128*128
#红方防御塔:128*128
import pygame
from pygame.locals import *
pygame.init()
width,height = 1280,720
screen=pygame.display.set_mode((width,height))
Blue_player = pygame.image.load("G:/fan/Python/游戏/王者/image/Hero_Blue.png")
while 1:
screen.fill(0)
screen.blit(Blue_player,(100,100))
pygame.display.flip()
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit(0)
效果图
可以插入图片了,就先布局好?
5.使蓝方玩家可以移动
在#2设置一个变量Hero_Blue_pos=[30,30]
WASFD键:keys = [False, False, False, False]
#妲己:512*528 156*156
#娜可露露:156*156
#蓝方防御塔128*128
#红方防御塔:128*128
# 1
import pygame
from pygame.locals import *
# 2
pygame.init()
width,height = 1280,720
screen=pygame.display.set_mode((width,height))
keys = [False, False, False, False]
Hero_Blue_pos=[30,30]
# 3 加载图片
Blue_player = pygame.image.load("image/Hero_Blue.png")
bg_haidu = pygame.image.load("image/bg_haidu.jpg")
Hero_Blue_ = pygame.image.load("image/Hero_Blue_.png")
Hero_Red_ = pygame.image.load("image/Hero_Red_.png")
Blue_Tower1 = pygame.image.load("image/Blue_Tower1.png")
Blue_Tower2 = pygame.image.load("image/Blue_Tower2.png")
Blue_Tower3 = pygame.image.load("image/Blue_Tower3.png")
Red_tower1 = pygame.image.load("image/Red_tower1.png")
Red_tower2 = pygame.image.load("image/Red_tower2.png")
Red_tower3 = pygame.image.load("image/Red_tower3.png")
#4
while 1:
# 5
screen.fill(0)
# 6
screen.blit(bg_haidu,(0,0))
#screen.blit(Blue_player,(100,100))
#大一点的小妲己(这个后面的图片会盖在前面的图片上
screen.blit(Hero_Blue_,Hero_Blue_pos)
screen.blit(Blue_Tower1,(33,227.25))
screen.blit(Blue_Tower2,(33,391.5))
screen.blit(Blue_Tower3,(33,555.75))
screen.blit(Hero_Red_,(1119,30))
screen.blit(Red_tower1,(1119,227.25))
screen.blit(Red_tower2,(1119,391.5))
screen.blit(Red_tower3,(1119,555.75))
# 7
pygame.display.flip()
# 8
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit(0)
接下来,根据按下的键来更新按键记录数组。PyGame里用给按键添加事件的方法来检测按键。
在#8结尾,就在event.py == pygame.QUIT后面,添加一下的代码(与pygame.QUIT保持同级别缩进):
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
首先,你检查是否有一个键被按下或放开。然后,检查是哪一个键被按下或放开了,如果被按下或放开的键是你使用的,你就更新记录按键的变量。
最终,你需要更新playerpos变量作为按键后的反应。这实际上是非常简单的。
把一下的代码加到game.py的结尾:(让它与for 循环保持同级别缩进)
# 9 - Move player
if keys[0]:
Hero_Blue_pos[1]-=5
elif keys[2]:
Hero_Blue_pos[1]+=5
if keys[1]:
Hero_Blue_pos[0]-=5
elif keys[3]:
Hero_Blue_pos[0]+=5
可以了?
6.转向
import math
把#6部分的最后一行用一下代码替换:
# 6.1 - Set player position and rotation
position = pygame.mouse.get_pos()
angle = math.atan2(position[1]-(Hero_Blue_pos[1]+88),position[0]-(Hero_Blue_pos[0]+80.5))
Hero_Blue_rot = pygame.transform.rotate(Hero_Blue_, 360-angle*57.29)
Hero_Blue_pos1 = (Hero_Blue_pos[0]-Hero_Blue_rot.get_rect().width/2, Hero_Blue_pos[1]-Hero_Blue_rot.get_rect().height/2)
screen.blit(Hero_Blue_rot, Hero_Blue_pos1)
7.射箭
在#2声明的部分加上必要的变量的声明。
acc=[0,0]
arrows=[]
第一个变量会跟踪玩家的精度,第二个变量会跟踪箭头。这个精度的变量本质上是一个数字组成的列表,记录了射出的箭头数和被击中的獾的数量。之后我们会用到这些信息用来计算射击精确度。
接下来,在#3部分结尾加载箭头的图片。
arrow = pygame.image.load("image/bullet.png")
在#8部分加上以下代码:
#点击鼠标射出箭头
if event.type==pygame.MOUSEBUTTONDOWN:
position=pygame.mouse.get_pos()
acc[1]+=1
arrows.append([math.atan2(position[1]-(Hero_Blue_pos1[1]+88),position[0]-(Hero_Blue_pos1[0]+80.5)),Hero_Blue_pos1[0]+88,Hero_Blue_pos1[1]+80.5])
这段代码会检查是否鼠标被点击了,如果点击了,它就会得到鼠标的位置并且根据玩家和光标的位置计算出箭头旋转角度。旋转角度的值存放在arrows这个数组里。
接下来,你需要真的在屏幕上画出箭头来。在#6部分加上以下代码:
# 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
#参数991表示不会射出塔
if bullet[1]<-156 or bullet[1]>991 or bullet[2]<-156 or bullet[2]>720:
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]))
8.愤怒的娜可露露守塔
在这一步,你将会随机创建出一些小兵冲向城堡。在游戏的进程中会有越来越多的兵冒出来。所以,我们来列个接下来要做的事情的清单。
- 添加一个兵的列表
- 更新兵的信息,并且检查它们是否超出屏幕范围
- 展示这些兵
第一步,在#2部分加上一下代码:
badtimer=100
badtimer1=0
badguys=[[640,100]]
healthvalue=194
以上的代码里定义了一个定时器,使得游戏里可以经过一段时间后就新建一只兵
在#3部分结尾处添加以下代码:
badguyimg1 = pygame.image.load("image/badguy.png")
badguyimg=badguyimg1
第一行跟前面加载图片的代码很相似。第二行声明了一个图片的复制。
接下来,你需要更新并且显示这些坏蛋了。在#6.2部分加上以下代码:
# 6.3 - Draw badgers
if badtimer==0:
badguys.append([1091, random.randint(191,529)])
badtimer=100-(badtimer1*2)
if badtimer1>=35:
badtimer1=35
else:
badtimer1+=5
index=0
for badguy in badguys:
if badguy[0]<-64:
badguys.pop(index)
badguy[0]-=7
index+=1
for badguy in badguys:
screen.blit(badguyimg, badguy)
上面的代码看起来有不少。第一行是来检查badtime是否为0,如果为0,创建一个兵然后重新设置badtime。第一个循环更新兵的x坐标,检查兵是否超出屏幕范围,如果超出范围,将兵删掉。第二个循环是来画出所有的兵。
为了在以上代码里用到随机的功能,你需要导入random库。所以在#1部分加上导入的代码:
import random
最后,把一行代码添加到#4部分的while表达式后面:
badtimer-=1
把以下代码加到#6.3部分index+=1之前的第一个循环里:
# 6.3.1 - Attack castle
badrect=pygame.Rect(badguyimg.get_rect())
badrect.top=badguy[1]
badrect.left=badguy[0]
if badrect.left<64:
healthvalue -= random.randint(5,20)
badguys.pop(index)
# 6.3.3 - Next bad guy
这段代码相当简单。如果兵的x坐标离右边小于64,就删除坏蛋并且减少游戏里的健康值,减少的大小为5至20里的一个随机数。
再次运行这个游戏,你就会有一些兵冲过来并且在碰到城堡的时候会消失。尽管你看不到,兵实际上会降低你的健康值。
9.兵与箭头的碰撞
在#6.3.1部分后面加这些:
#6.3.2 - Check for collisions
index1=0
for bullet in arrows:
bullrect=pygame.Rect(arrow.get_rect())
bullrect.left=bullet[1]
bullrect.top=bullet[2]
if badrect.colliderect(bullrect):
acc[0]+=1
badguys.pop(index)
arrows.pop(index1)
index1+=1
这段代码里面只有一个地方需要提一下,这个if表达式使用了PyGame内建功能来检查两个矩形是否交叉。接下来的一些代码跟上面说的一样。
再运行下代码,现在你就可以用箭头来杀死兵了。
10.添加健康值和时间的显示
现在游戏运行起来相当不错了。现在有攻击者,有防守者。现在,你需要的就是通过一个方法来显示兔子的得分。
最简单的方法就是添加一个HUD来显示当前城堡的生命值。你也可以加一个计时来记录城堡存活下来的时间。
首先,添加一个计时。在#7部分加上下面的代码:
# 6.4 - Draw clock
font = pygame.font.Font(None, 24)
survivedtext = font.render(str((90000-pygame.time.get_ticks())/60000)+":"+str((90000-pygame.time.get_ticks())/1000%60).zfill(2), True, (0,0,0))
textRect = survivedtext.get_rect()
textRect.topright=[1275,5]
screen.blit(survivedtext, textRect)
上面的代码使用了PyGame默认的大小为24的字体。这个字体用来显示时间信息。
healthbar = pygame.image.load("image/healthbar.png")
health = pygame.image.load("image/health.png")
接下来添加代码到#6.4部分后面:
# 6.5 - Draw health bar
screen.blit(healthbar, (5,5))
for health1 in range(healthvalue):
screen.blit(health, (health1+8,8))
这段代码首先画了一个全红色的生命值条。然后根据城堡的生命值往生命条里面添加绿色。
运行下代码,现在就会有计时和生命值条了。
11.赢或输
我们来加上胜利或者失败的条件。你可以通过终止主循环,进入胜利/失败的循环来实现它。你需要指出玩家是否胜利,并将其显示在屏幕上。
下面是一些胜利/失败的一些基本条件:
如果时间到了(90秒)那么:
- 停止运行游戏
- l设置游戏的输出
如果城堡被毁,那么:
- 停止运行游戏
- l设置游戏的输出
精确度是一直都需要计算的。
在game.py 结尾添加这些代码
#10 - Win/Lose check
if pygame.time.get_ticks()>=90000:
running=0
exitcode=1
if healthvalue<=0:
running=0
exitcode=0
if acc[1]!=0:
accuracy=acc[0]*1.0/acc[1]*100
else:
accuracy=0
# 11 - Win/lose display
if exitcode==0:
pygame.font.init()
font = pygame.font.Font(None, 24)
text = font.render("Accuracy: "+str(accuracy)+"%", True, (255,0,0))
textRect = text.get_rect()
textRect.centerx = screen.get_rect().centerx
textRect.centery = screen.get_rect().centery+24
screen.blit(defeat, (0,0))
screen.blit(text, textRect)
else:
pygame.font.init()
font = pygame.font.Font(None, 24)
text = font.render("Accuracy: "+str(accuracy)+"%", True, (0,255,0))
textRect = text.get_rect()
textRect.centerx = screen.get_rect().centerx
textRect.centery = screen.get_rect().centery+24
screen.blit(victory, (0,0))
screen.blit(text, textRect)
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
pygame.display.flip()
第一个ifb表达式是检查是否时间到了。第二个是检查城堡是否被摧毁了。第三个计算你的精准度。之后,一个if表达式是检查你是赢了还是输了,然后显示出相应的图片。
当然,如果你想在赢或输的时候显示图片,这些图片首先需要加载。所以在#3部分加上这些代码:
defeat = pygame.image.load("image/defeat.png")
victory = pygame.image.load("image/victory.png")
还有需要改的地方,把#4部分从:
# 4 - keep looping through
while 1:
badtimer-=1
改成:
# 4 - keep looping through
running = 1
exitcode = 0
while running:
badtimer-=1
这个running变量会跟踪游戏是否结束,exitcode变量会跟踪玩家是否胜利。
12.添加声音
在#2部分结尾加上这些代码:
pygame.mixer.init()
然后在#3部分加载声音然后设置声音:
# 3.1 - Load audio
hit = pygame.mixer.Sound("audio/explode.wav")
enemy = pygame.mixer.Sound("audio/enemy.wav")
shoot = pygame.mixer.Sound("audio/shoot.wav")
hit.set_volume(0.05)
enemy.set_volume(0.05)
shoot.set_volume(0.05)
#pygame.mixer.music.load("audio/moonlight.wav")
pygame.mixer.music.load("audio/wangzhe.wav")
pygame.mixer.music.play(-1, 0.0)
pygame.mixer.music.set_volume(0.25)
上面大部分代码就是加载声音文件并且配置音量。但是注意 pygame.mixer.music.load这行代码——这一行加载游戏的背景音乐然后下一行让背景音乐一直不停的播放。
现在注意声音的配置。现在你所有需要做的就是在需要的时候播放不同的音乐。
# section 6.3.1 after if badrect.left<64:
hit.play()
# section 6.3.2 after if badrect.colliderect(bullrect):
enemy.play()
# section 8, after if event.type==pygame.MOUSEBUTTONDOWN:
shoot.play()
再次运行游戏,你会发现现在有背景音乐了,并且在射出箭头和碰撞的时候会有音效。
全部代码
#妲己:512*528 156*156
#娜可露露:156*156
#蓝方防御塔128*128
#红方防御塔:128*128
# 1
import pygame
from pygame.locals import *
import math
import random
# 2
pygame.init()
width,height = 1280,720
screen=pygame.display.set_mode((width,height))
keys = [False, False, False, False]
#Hero_Blue_pos=[30,30]
Hero_Blue_pos=[130,130]
acc=[0,0]
arrows=[]
badtimer=100
badtimer1=0
badguys=[[640,100]]
healthvalue=194
pygame.mixer.init()
# 3 加载图片
#Blue_player = pygame.image.load("image/xiaodaji.png")
bg_haidu = pygame.image.load("image/bg_haidu.jpg")
Hero_Blue_ = pygame.image.load("image/Hero_Blue_.png")
Hero_Red_ = pygame.image.load("image/Hero_Red_.png")
Blue_Tower1 = pygame.image.load("image/Blue_Tower1.png")
Blue_Tower2 = pygame.image.load("image/Blue_Tower2.png")
Blue_Tower3 = pygame.image.load("image/Blue_Tower3.png")
Red_tower1 = pygame.image.load("image/Red_tower1.png")
Red_tower2 = pygame.image.load("image/Red_tower2.png")
Red_tower3 = pygame.image.load("image/Red_tower3.png")
arrow = pygame.image.load("image/bullet.png")
badguyimg1 = pygame.image.load("image/badguy.png")
badguyimg=badguyimg1
healthbar = pygame.image.load("image/healthbar.png")
health = pygame.image.load("image/health.png")
fefeat = pygame.image.load("image/defeat.png")
victory = pygame.image.load("image/victory.png")
#添加声音
# 3.1 - Load audio
hit = pygame.mixer.Sound("audio/explode.wav")
enemy = pygame.mixer.Sound("audio/enemy.wav")
shoot = pygame.mixer.Sound("audio/shoot.wav")
hit.set_volume(0.05)
enemy.set_volume(0.05)
shoot.set_volume(0.05)
#pygame.mixer.music.load("audio/moonlight.wav")
pygame.mixer.music.load("audio/wangzhe.wav")
pygame.mixer.music.play(-1, 0.0)
pygame.mixer.music.set_volume(0.25)
#4
running = 1
exitcode = 0
while running:
badtimer-=1
# 5
screen.fill(0)
# 6
screen.blit(bg_haidu,(0,0))
#screen.blit(Blue_player,(100,100))
#大一点的小妲己(这个后面的图片会盖在前面的图片上
screen.blit(Blue_Tower1,(33,227.25))
screen.blit(Blue_Tower2,(33,391.5))
screen.blit(Blue_Tower3,(33,555.75))
screen.blit(Hero_Red_,(1119,30))
screen.blit(Red_tower1,(1119,227.25))
screen.blit(Red_tower2,(1119,391.5))
screen.blit(Red_tower3,(1119,555.75))
#screen.blit(Hero_Blue_,Hero_Blue_pos)
# 6.1 - Set player position and rotation
position = pygame.mouse.get_pos()
angle = math.atan2(position[1]-(Hero_Blue_pos[1]+88),position[0]-(Hero_Blue_pos[0]+80.5))
Hero_Blue_rot = pygame.transform.rotate(Hero_Blue_, 360-angle*57.29)
Hero_Blue_pos1 = (Hero_Blue_pos[0]-Hero_Blue_rot.get_rect().width/2, Hero_Blue_pos[1]-Hero_Blue_rot.get_rect().height/2)
screen.blit(Hero_Blue_rot, Hero_Blue_pos1)
# 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
#参数991表示不会射出塔
if bullet[1]<-156 or bullet[1]>991 or bullet[2]<-156 or bullet[2]>720:
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]))
# 6.3 - Draw badgers
if badtimer==0:
badguys.append([1091, random.randint(191,529)])
badtimer=100-(badtimer1*2)
if badtimer1>=35:
badtimer1=35
else:
badtimer1+=5
index=0
for badguy in badguys:
# 6.3.1 - Attack castle
badrect=pygame.Rect(badguyimg.get_rect())
badrect.top=badguy[1]
badrect.left=badguy[0]
if badrect.left<64:
hit.play()
healthvalue -= random.randint(5,20)
badguys.pop(index)
#6.3.2 - Check for collisions
index1=0
for bullet in arrows:
bullrect=pygame.Rect(arrow.get_rect())
bullrect.left=bullet[1]
bullrect.top=bullet[2]
if badrect.colliderect(bullrect):
enemy.play()
acc[0]+=1
badguys.pop(index)
arrows.pop(index1)
index1+=1
# 6.3.3 - Next bad guy
if badguy[0]<-64:
badguys.pop(index)
badguy[0]-=7
index+=1
for badguy in badguys:
screen.blit(badguyimg, badguy)
# 6.4 - Draw clock
font = pygame.font.Font(None, 24)#使用PyGame默认的大小为24的字体
survivedtext = font.render(str((90000-pygame.time.get_ticks())/60000)[:1]+":"+str((90000-pygame.time.get_ticks())/1000%60)[:4].zfill(2), True, (255,255,255))
#上一行代码使用字符串切片操作保留整数;(255,255,255)把颜色设置为白色
textRect = survivedtext.get_rect()
textRect.topright=[1250,5]
screen.blit(survivedtext, textRect)
# 6.5 - Draw health bar
screen.blit(healthbar, (5,5))
for health1 in range(healthvalue):
screen.blit(health, (health1+8,8))
# 7
pygame.display.flip()
# 8
for event in pygame.event.get():
#if event.type==pygame.QUIT:
# pygame.quit()
# exit(0)
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 event.type==pygame.MOUSEBUTTONDOWN:
shoot.play()
position=pygame.mouse.get_pos()
acc[1]+=1
arrows.append([math.atan2(position[1]-(Hero_Blue_pos1[1]+88),position[0]-(Hero_Blue_pos1[0]+80.5)),Hero_Blue_pos1[0]+88,Hero_Blue_pos1[1]+80.5])
# 9 - Move player
if keys[0]:
Hero_Blue_pos[1]-=5
elif keys[2]:
Hero_Blue_pos[1]+=5
if keys[1]:
Hero_Blue_pos[0]-=5
elif keys[3]:
Hero_Blue_pos[0]+=5
if event.type==pygame.QUIT:
pygame.quit()
exit(0)
#10 - Win/Lose check
if pygame.time.get_ticks()>=90000:
running=0
exitcode=1
if healthvalue<=0:
running=0
exitcode=0
if acc[1]!=0:
accuracy=acc[0]*1.0/acc[1]*100
accuracy = round(accuracy,2)#保留小数点后两位
else:
accuracy=0
# 11 - Win/lose display
if exitcode==0:
pygame.font.init()
font = pygame.font.Font(None, 24)
text = font.render("Accuracy: "+str(accuracy)+"%", True, (255,0,0))
textRect = text.get_rect()
textRect.centerx = screen.get_rect().centerx
textRect.centery = screen.get_rect().centery+24
screen.blit(fefeat, (0,0))
screen.blit(text, textRect)
else:
pygame.font.init()
font = pygame.font.Font(None, 24)
text = font.render("Accuracy: "+str(accuracy)+"%", True, (0,255,0))
textRect = text.get_rect()
textRect.centerx = screen.get_rect().centerx
textRect.centery = screen.get_rect().centery+24
screen.blit(victory, (0,0))
screen.blit(text, textRect)
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
pygame.display.flip()
文件的话emmmmm……自己找吧