用pygame制作小宝贝的算术练习游戏
一、游戏基本设想
上过一些像有道数学这些在线培训项目的体验课。对这些APP用游戏进行教学的思路非常的赞同。不过这些APP的订阅费用不菲,按年计都在数千元左右。而且最近新出台的课外培训监管政策,不知会不会有什么影响?所以预付款也有很大的风险。最关键的因素还是性价比太低了,因为小孩的启蒙课程难度都很低。如果懂编程的话,完全也可以自己动手来开发。
今天我做的这个是让小朋友练习10以内加法的小游戏。游戏的规则是。在屏幕上方给出题目,下面给出三个候选答案。小朋友可以通过箭头控制小人的移动,将小人移动到正确答案的数字下面。点击小人,如果答案正确。小人就会跳上数字方块的上面。如果答错了,小人就会落回地面。
二、pygame最小系统
因为前段时间学习了用派生语言的拍game模组进行游戏编程,所以这个游戏也是用拍game来编写,拍game编写游戏,有一个最小系统,可以显示一个全黑的屏幕,然后在此基础上不断的增加内容。
import pygame
pygame.init()
screen = pygame.display.set_mode((400,800))
running = True
while running:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((0,0,0))
pygame.display.update()
三、精灵(sprite)系统
pygame模组中有一个精灵系统,可以非常方便的将游戏对象组织进不同的精灵主实现碰撞检测,图像刷新,图像取消显示等功能。
在这个游戏中我设置了玩家精灵。候选答案砖块精灵。题目栏精灵和控制键精灵。
四、源代码
# -*- coding: utf-8 -*-
import pygame
import random
gravity = 1.2
support = 0
pygame.init()
screen = pygame.display.set_mode((400,800))#,pygame.FULLSCREEN|pygame.SCALED)
background = pygame.image.load('image\Background.jpg')
background = pygame.transform.smoothscale(background,(400,800))
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('image\player.jpg').convert()
pygame.Surface.set_colorkey(self.image,(0,0,0))
self.image = pygame.transform.smoothscale(self.image,(80,90))
# self.image = pygame.Surface((50,50))
# self.image.fill((0,255,0))
self.rect=self.image.get_rect()
self.rect.center =(200,700)
self.vel_x = 0
self.vel_y = 0
self.jumping = False
self.last_update = 0
def update(self):
global gravity
global support
self.vel_y += gravity+support
self.rect=self.rect.move(self.vel_x,self.vel_y)
if self.rect.right < 0:
self.rect.left = 400
if self.rect.left > 400:
self.rect.right = 0
if self.rect.bottom >= 725:
self.rect.bottom =725
support = -1*gravity
self.jumping = False
else:
support = 0
if support == 0:
self.jumping = True
class brick(pygame.sprite.Sprite):
def __init__(self,center_x,center_y,answer_number,idx):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50,50))
self.image.fill((255,0,0))
self.rect=self.image.get_rect()
self.rect.center =(center_x,center_y)
self.font = pygame.font.Font('segoeprb.ttf',32)
self.answer_number = answer_number
self.idx = idx
def update(self):
self.image.fill((255,0,0))
choice_number = self.font.render(str(self.answer_number),True,(0,255,0))
self.image.blit(choice_number,(5,-10))
class question_banner(pygame.sprite.Sprite):
def __init__(self,center_x,center_y,question):
pygame.sprite.Sprite.__init__(self)
self.text = question
self.font = pygame.font.Font('segoeprb.ttf',64)
self.image = pygame.Surface((300,80))
self.image.fill((0,0,255))
self.rect=self.image.get_rect()
self.rect.center =(center_x,center_y)
def update(self):
question_img = self.font.render(self.text,True,(255,0,0))
self.image.blit(question_img,(10,-10))
class contral(pygame.sprite.Sprite):
def __init__(self,image,x,y):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load(image)
self.image = pygame.transform.smoothscale(self.image,(60,40))
self.rect = self.image.get_rect()
self.rect.center = (x,y)
def update(self):
pass
adds_num=[1,1]
all_sprites= pygame.sprite.Group()
player = Player()
brick1 = brick(80,600,1,0)
brick2 = brick(200,600,2,1)
brick3 = brick(320,600,3,2)
QuestionBanner = question_banner(200,100,str(adds_num[0])+'+'+str(adds_num[1])+'=?')
right_arrow = contral('image\Right.png',350,750)
left_arrow = contral('image\Left.png',50,750)
all_sprites.add(player,brick1,brick2,brick3,QuestionBanner,right_arrow,left_arrow)
bricks = pygame.sprite.Group()
bricks.add(brick1,brick2,brick3)
clock = pygame.time.Clock()
def update_question(pre_idx=1):
answers=random.sample(range(1,11),3)
brick1.answer_number=answers[0]
brick2.answer_number=answers[1]
brick3.answer_number=answers[2]
idx=random.sample(range(0,3),1)[0]
while idx == pre_idx:
idx=random.sample(range(0,3),1)[0]
adds_num[0]=random.randint(0,answers[idx])
adds_num[1]=answers[idx]-adds_num[0]
QuestionBanner.image.fill((0,0,255))
QuestionBanner.text = str(adds_num[0])+'+'+str(adds_num[1])+'=?'
running = True
while running:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN and event.button ==1:
if left_arrow.rect.collidepoint(event.pos):
player.vel_x -= 5
elif right_arrow.rect.collidepoint(event.pos):
player.vel_x = 5
if player.rect.collidepoint(event.pos):
player.vel_y = -20
elif event.type == pygame.MOUSEBUTTONUP:
player.vel_x = 0
#update
all_sprites.update()
hits = pygame.sprite.spritecollide(player,bricks,False)
if not hits:
ready2change_question = True
if hits and player.vel_y > 0:
player.last_update = pygame.time.get_ticks()
if hits and player.vel_y >= 0:
if sum(adds_num)==hits[0].answer_number:
player.vel_y = 0
player.rect.bottom = hits[0].rect.top+1
support = -1*gravity
player.jumping = False
now = pygame.time.get_ticks()
if ready2change_question and now - player.last_update>3000:
update_question(hits[0].idx)
ready2change_question = False
#render
screen.blit(background,(0,0))
all_sprites.draw(screen)
pygame.display.update()
五、改进想法
游戏基本功能得以实现,不过缺乏游戏中的奖励和惩罚机制。我的想法是加入三个红星代表生命值,如果每答错一题就掉一个红星,同时加入记分,每答对一题就加一分。三条命都用完后记录最高分。通过这种办法激励小朋友。尽量准确的答题。并且挑战最高分数。
家里有小孩的网友,有什么好的创意。可以留言告知,如果有人有兴趣,达到一定完成度的时候,我会共享出来。
#cn #whalepower #lifestyle #cn-reader #kateschoice #jjm #life #cn-programming #steemace #battle #iv #zzan #dblog #diamondtoken #marlians #upfundme