Pygame - Python游戏编程入门(1)

前言

  在上一篇中,我们初步熟悉了pygame的控制流程,但这对于一个游戏而言是远远不够的。所以在这一篇中,我们的任务是添加一架飞机(玩家),并且能够控制它进行移动,这样我们就又离目标进了一步了~ε=ε=(ノ≧∇≦)ノ

 

正片开始!

1. 把我们的战斗机搬上屏幕

  在正式上代码以前,有一点需要说明的,我们可以看到,所有屏幕上出现的元素都在资源文件(resources/image/shoot.png)中,那我们要怎么做才能把一只飞机给裁剪出来呢?在pygame中,所有在屏幕上显示的元素都可以视为一个surface,利用这个特点,我们可以把资源文件导入(load()函数),然后用surface.subsurface()函数把shoot.png中我们想要的元素裁剪出来,这样问题就解决了~(tips:怎样才知道shoot.png中飞机的准确坐标呢?在resources/image/shoot.pack文件中已经详细记录了每个屏幕元素的左上角坐标以及它的宽和高了)

  先上代码:(在注释# == new add ==之间的代码为新加入代码)

 1 import pygame                   # 导入pygame库
 2 from pygame.locals import *     # 导入pygame库中的一些常量
 3 from sys import exit            # 导入sys库中的exit函数
 4 
 5 # 定义窗口的分辨率
 6 SCREEN_WIDTH = 480
 7 SCREEN_HEIGHT = 640
 8 
 9 # 计数ticks == new add ==
10 ticks = 0
11 # 计数ticks == new add ==
12   
13 # 初始化游戏
14 pygame.init()                   # 初始化pygame
15 screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])     # 初始化窗口
16 pygame.display.set_caption('This is my first pygame-program')       # 设置窗口标题
17 
18 # 载入背景图
19 background = pygame.image.load('resources/image/background.png')
20 
21 # 载入资源图片 == new add ==
22 shoot_img = pygame.image.load('resources/image/shoot.png')
23 # 用subsurface剪切读入的图片
24 hero1_rect = pygame.Rect(0, 99, 102, 126)
25 hero2_rect = pygame.Rect(165, 360, 102, 126)
26 hero1 = shoot_img.subsurface(hero1_rect)
27 hero2 = shoot_img.subsurface(hero2_rect)
28 hero_pos = [200, 500]
29 # 载入资源图片 == new add ==
30 
31 # 事件循环(main loop)
32 while True:
33 
34     # 绘制背景
35     screen.blit(background, (0, 0))
36     
37     # 绘制飞机 == new add ==
38     if ticks % 50 < 25:
39         screen.blit(hero1, hero_pos)
40     else:
41         screen.blit(hero2, hero_pos)
42     ticks += 1
43     # 绘制飞机  == new add ==
44     
45     # 更新屏幕
46     pygame.display.update()                                         
47     
48     # 处理游戏退出
49     # 从消息队列中循环取
50     for event in pygame.event.get():
51         if event.type == pygame.QUIT:
52             pygame.quit()
53             exit()

不妨运行一下:

  

可以看到,我们的飞机动了,究竟是怎样实现动画效果的呢?在代码中,新加入的代码一共有三处,显示玩家飞机的那一段已经解释过了,现在我们来解释其余的两段新加入的代码。首先增加了一个计数变量ticks,在消息循环中,每循环一次就累加一次,可以理解为每一个周期就是1 tick,我们可以利用周期数来分隔不同的显示效果;我们读入了两张不同的玩家飞机图片,利用周期数实现每50个周期,前25个周期显示hero1,后25个周期显示hero2,这样就有了缓慢变化的动态效果。不过值得注意的是,这样每一次循环就计算判断一次ticks的做法明显不是好方法。还有!(╯°口°)╯(┴—┴,Python是木有自增表达式的,我试图++ticks结果报错了。

  战斗机已经准备就绪,该教会飞行员怎样操作了~(`・ω・´)

 

2. 用键盘控制飞机移动

  我们知道,每敲一下键盘都会产生一个事件,而这个事件能被Python检测到,既然知道了这个大前提,那控制飞机就很容易了。

  come on code~ ( °∀°)ノ

 1 import pygame                   # 导入pygame库
 2 from pygame.locals import *     # 导入pygame库中的一些常量
 3 from sys import exit            # 导入sys库中的exit函数
 4 
 5 # 定义窗口的分辨率
 6 SCREEN_WIDTH = 480
 7 SCREEN_HEIGHT = 640
 8 
 9 ticks = 0
10 # dict == new add ==
11 offset = {pygame.K_LEFT:0, pygame.K_RIGHT:0, pygame.K_UP:0, pygame.K_DOWN:0}
12 # dict == new add ==
13   
14 # 初始化游戏
15 pygame.init()                   # 初始化pygame
16 screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])     # 初始化窗口
17 pygame.display.set_caption('This is my first pygame-program')       # 设置窗口标题
18 
19 # 载入背景图
20 background = pygame.image.load('resources/image/background.png')
21 
22 # 载入飞机图片
23 shoot_img = pygame.image.load('resources/image/shoot.png')
24 # 用subsurface剪切读入的图片
25 hero1_rect = pygame.Rect(0, 99, 102, 126)
26 hero2_rect = pygame.Rect(165, 360, 102, 126)
27 hero1 = shoot_img.subsurface(hero1_rect)
28 hero2 = shoot_img.subsurface(hero2_rect)
29 hero_pos = [200, 500]
30 
31 # 事件循环(main loop)
32 while True:
33 
34     # 绘制背景
35     screen.blit(background, (0, 0))
36 
37     # 绘制飞机
38     if ticks % 50 < 25:
39         screen.blit(hero1, hero_pos)
40     else:
41         screen.blit(hero2, hero_pos)
42     ticks += 1 # python已略去自增运算符
43 
44     # 更新屏幕
45     pygame.display.update()                                         
46     
47     # 处理游戏退出
48     # 从消息队列中循环取
49     for event in pygame.event.get():
50         if event.type == pygame.QUIT:
51             pygame.quit()
52             exit()
53 
54         # Python中没有switch-case 多用字典类型替代
55         # 控制方向 == new add ==          
56         if event.type == pygame.KEYDOWN:
57             if event.key in offset:
58                 offset[event.key] = 3
59         elif event.type == pygame.KEYUP:
60             if event.key in offset:
61                 offset[event.key] = 0
62 
63         # part 1
64         #offset_x = offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
65         #offset_y = offset[pygame.K_DOWN] - offset[pygame.K_UP]
66         #hero_pos = [hero_pos[0] + offset_x, hero_pos[1] + offset_y]
67     # part 2
68     offset_x = offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
69     offset_y = offset[pygame.K_DOWN] - offset[pygame.K_UP]
70     hero_pos = [hero_pos[0] + offset_x, hero_pos[1] + offset_y]
71     # 控制方向 == new add ==          

新加入了两处,一个是字典类型的变量,一个是控制方向的代码。跟之前控制程序退出的代码一样,依然是从事件队列中取事件;当event.type为按键事件时,再判断event.key是否属于上下左右四个键位中的其中一个;最后在其相应方向上给一个偏移量,即完成判断的过程;松键的话该方向上的偏移量赋值为0,这样该键方向上就没有位移了;最后将偏移量加到飞机的pos上,下一轮刷新时自然就到移动到新地方了。(这里插播一个事,我以前写过c++和java,所以写到判断键盘键位时,很自然就想用switch-case语句,没想到竟然出错了(╯°口°)╯(┴—┴,后来才发现原来Python是没有switch-case语句的,switch-case语句多用字典数据结构代替,感觉这样的写法就更灵活了)

上面讲得都比较简单,现在我们要思考一个问题,上面的代码中,line 63-66和line 67-70的代码是一样的,但两部分代码的效果却是很不一样。part1代码使得我们要按一次键飞机才会动一次,而在part2代码中我们可以长按方向键来控制飞机,不禁感慨一下Python的缩进。part1是在for循环的影响下的,也就是说,事件队列中有事件才会执行part1的代码,假设我们长按方向左键(注意,击键一次只会产生一个pygame.KEYDOWN事件,所以长按也只触发一次),飞机也只会往左移3个像素点;而part2代码由于不在for循环内,所以每一tick就向左移3个像素点直到松开方向左键。

演示一下效果:

好的,控制飞机已经不成问题了,不过大家发现飞机有一个小问题了吗?它会穿到窗口的“外面”去!不过我们只要添加一个小小的限制就可以解决问题了,只要把line68-70换成以下边界判断代码就可以了。

 1     hero_x = hero_pos[0] + offset[pygame.K_RIGHT] - offset[pygame.K_LEFT]
 2     hero_y = hero_pos[1] + offset[pygame.K_DOWN] - offset[pygame.K_UP]
 3     if hero_x < 0:
 4         hero_pos[0] = 0
 5     elif hero_x > SCREEN_WIDTH - hero1_rect.width:
 6         hero_pos[0] = SCREEN_WIDTH - hero1_rect.width
 7     else:
 8         hero_pos[0] = hero_x
 9         
10     if hero_y < 0:
11         hero_pos[1] = 0
12     elif hero_y > SCREEN_HEIGHT - hero1_rect.height:
13         hero_pos[1] = SCREEN_HEIGHT - hero1_rect.height
14     else:
15         hero_pos[1] = hero_y

今天功能就完成到这里吧~(`・ω・´)

 

转载于:https://www.cnblogs.com/wuzhanpeng/p/4264267.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259422.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AQS浅析

2019独角兽企业重金招聘Python工程师标准>>> AQS的原理浅析 本文是《Java特种兵》的样章&#xff0c;本书即将由工业出版社出版 AQS的全称为&#xff08;AbstractQueuedSynchronizer&#xff09;&#xff0c;这个类也是在java.util.concurrent.locks下面。这个类似乎…

编程如写作

昨晚似乎是个适合写作的夜&#xff0c;不论是自己还是朋友&#xff0c;都比平常更容易被触动。看着微博上朋友们的心路&#xff0c;想写点什么却似乎找不出非常值得大书特书的主题&#xff0c;只是歪坐在电脑旁&#xff0c;喝着咖啡&#xff0c;单曲循环着仓木麻衣的《time aft…

工作环境总结(1)开发环境搭建

1、安装git 安装文件&#xff1a;Git-2.12.0-64-bit.exe 下载地址&#xff1a;https://github.com/git-for-windows/git/releases/download/v2.12.0.windows.1/Git-2.12.0-64-bit.exe 在git bash中配置&#xff0c;git bash命令行中执行&#xff08;只有使用到egit时使用&…

15款的视频处理软件免费下载

因为需要购买昂贵的视频处理软件和高性能图形计算机&#xff0c;所以视频处理是一项比较耗费金钱的技术活。正是由于这样&#xff0c;一部分人选择使用性能较好的免费在线编辑软件&#xff0c;无需太多视频处理知识便可在浏览器中剪切和编辑视频。然而&#xff0c;当我们无法连…

液位系统c语言程序,超声波自动测量物体液位系统的设计

超声波自动测量物体液位系统的设计(任务书,毕业论文15000字)摘要本系统以STC89C52单片机为核心&#xff0c;通过硬件电路连接和软件程序的编写实现通用型超声波自动测量物体液位系统的设计。其主要原理是由单片机控制超声波发射电路发射超声波&#xff0c;超声波接收电路接收遇…

android-sdk-windows版本号下载

Android SDK 4.0.3 开发环境配置及执行 近期又装了一次最新版本号的ADK环境 眼下最新版是Android SDK 4.0.3 本文的插图和文本尽管是Android2.2的 步骤都是一样的&#xff0c;假设安装的过程中遇到什么问题&#xff0c;能够留言&#xff0c;我会尽快回复&#xff01; 系统环境的…

emacs-w3m查看html帮助手册

<?xml version"1.0" encoding"utf-8"?> emacs-w3m查看html帮助手册emacs-w3m查看html帮助手册 Table of Contents 1. 使用效果2. 为什么要用emacs-w3m来查看html的帮助手册&#xff1f;3. 什么是w3m?4. 配置5. 额外资源1 使用效果 使用快捷键C-c …

工作中的问题

今天写一专题页面&#xff0c;写出的结果在各个浏览器下都不同&#xff0c;心情不好。。。 就是红线的地方老对不齐。。。 在朋友指导下改了下样式好了 右边代码结构 1 <div class"fr Img"> 2 <h3>相关专题</h3> 3 <a href"#"…

数据结构行编辑成簇 c语言,索引的数据结构及底层存储

索引是帮助数据库高效获取数据的数据结构索引的数据结构1.hash表a.利用hash存储的话需要将所有的数据文件添加到内存&#xff0c;比较耗费内存空间b.hash表存储的是无序数据&#xff0c;范围查找的时候需要挨个进行遍历&#xff0c;比较耗费时间。2.二叉树二叉树规定左子树必须…

The C Programming Language--可变参数的函数

函数 printf的正确声明形式为&#xff1a;int printf(char *fmt, ...) void va_start (va list ap, last-required) type va_arg (va list ap, type) void va_end (va list ap) 其中&#xff0c;省略号表示参数表中参数的数量和类型是可变的。 va_list 类型用于声明一个变量&am…

cifar10 c语言,Python3读取深度学习CIFAR-10数据集出现的若干问题解决

今天在看网上的视频学习深度学习的时候&#xff0c;用到了CIFAR-10数据集。当我兴高采烈的运行代码时&#xff0c;却发现了一些错误&#xff1a;# -*- coding: utf-8 -*-import pickle as pimport numpy as np import os def load_CIFAR_batch(filename): """ 载…

各种排序算法总结

转载&#xff1a;http://blog.csdn.net/warringah1/article/details/8951220 明天就要去参加阿里巴巴的实习生笔试了&#xff0c;虽然没想着能进去&#xff0c;但是态度还是要端正的&#xff0c;也没什么可以准备的&#xff0c;复习复习排序吧。 1 插入排序 void InsertSort(in…

CentOS7 上安装 Zookeeper-3.4.9 服务

在 CentOS7 上安装 zookeeper-3.4.9 服务1、创建 /usr/local/services/zookeeper 文件夹&#xff1a; mkdir -p /usr/local/services/zookeeper 2、进入到 /usr/local/services/zookeeper 目录中&#xff1a; cd /usr/local/services/zookeeper 3、下载 zookeeper-3.4.9.…

HTTP响应报文与工作原理详解

HTTP 是一种请求/响应式的协议&#xff0c;即一个客户端与服务器建立连接后&#xff0c;向服务器发送一个请求;服务器接到请求后&#xff0c;给予相应的响应信息。 超文本传输协议(Hypertext Transfer Protocol&#xff0c;简称HTTP)是应用层协议。HTTP 是一种请求/响应式的协议…

android自定义画板,android 自定义控件 -- 画板

如图&#xff1a;package com.example.myview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Paint.Style;import android.util.Attrib…

postgreSQl pathman 用法语句总结

2019独角兽企业重金招聘Python工程师标准>>> --新建主表 create table part_test(id int, info text, crt_time timestamp not null); --插入测试数据 insert into part_test select id,md5(random()::text),clock_timestamp() (id|| hour)::interval from generat…

C#-面向对象的多态思想 ---ShinePans

总结: 多态是面向对象的核心.---------能够理解为一个方法,多种实现, 在这里能够用虚方法,抽象类,接口能够实现多态 1.首先利用接口来实现多态: 接口相当于"功能,"接口能够实现多继承,分为 显式实现接口和隐式实现接口 keyword为interface格式: interface 接口名 { …

android jar导出,Android项目导出jar包的小技巧

我们知道&#xff0c;可以通过如下设置将一个普通的Android工程转换成Android Library工程设置前后工程变化如下使用Ant编译时(通过android.bat update project 命令生成 build.xml)&#xff0c;普通的Android工程会生成apk文件&#xff0c;而Android Library工程只生成jar文件…

(五十九)iOS网络基础之UIWebView简易浏览器实现

【UIWebView网络浏览器】 通过webView的loadRequest方法可以发送请求显示相应的网站&#xff0c;例如&#xff1a; NSURL *url [NSURL URLWithString:"http://m.baidu.com"];// 创建请求数据NSURLRequest *request [NSURLRequest requestWithURL:url];// 向服务器发…

无心插柳OR志在必得?阿里推“来往”的意图

近年来&#xff0c;阿里巴巴在外围的动作确实不少&#xff0c;投资新浪微博、投资陌陌&#xff0c;配合阿里自身的一些战略调整&#xff0c;让人觉得这家公司似乎正在经历一场前所未有的“蜕变”。其实这也不难理解&#xff0c;在BAT三国演义中&#xff0c;任何一方都不能对其他…