我在使用pyGame时遇到问题(在此处完成新手操作)。我练习event.key,并且想取消/切断连续按下的键。我试图用谷歌搜索并检查了该站点,但是没有结果。整个事情都发生在
## HOW TO UNPRESS K_UP IN CASE IT WAS PRESSED AND NOT RELEASED?
if event.key == pygame.K_UP and isJumping == False:
yChange -= 10
isJumping = True
elif event.key == pygame.K_UP and isJumping == True:
print("X")
(第49-55行)
import pygame
pygame.init() # Initialize pyGame module
# Set screen dimensions
screenW = 800
screenH = 600
# Set color
AQUA = (155, 255, 255)
# Set FPS
FPS = 60
fpsClock = pygame.time.Clock()
# Set character
mainChar = pygame.image.load('p1_front.png')
mainCharX = screenH / 2 # char X position
mainCharY = screenW / 2 # char Y position
isJumping = False
xChange = 0
yChange = 0
MOVSPEED = 1
# Set backgrounds
mainBg = pygame.image.load('bg_castle.png')
mainBg = pygame.transform.scale(mainBg, (screenW, screenH))
# Set the window, param in a tuple is width / height
DISPLAYSURF = pygame.display.set_mode((screenW, screenH))
# Set window name (game title)
pygame.display.set_caption("Newbie training")
while True: # Main loop of the game
#set BG
DISPLAYSURF.blit(mainBg, (0,0))
# Events loop below
for event in pygame.event.get():
if event.type == pygame.QUIT: # Quit window when [x] is pressed
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
xChange += MOVSPEED
elif event.key == pygame.K_LEFT:
xChange -= MOVSPEED
## HOW TO UNPRESS K_UP IN CASE IT WAS PRESSED AND NOT RELEASED?
if event.key == pygame.K_UP and isJumping == False:
yChange -= 10
isJumping = True
elif event.key == pygame.K_UP and isJumping == True:
print("X")
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
xChange = 0
if event.key == pygame.K_UP:
yChange = 0
#print(event)
mainCharX += xChange
mainCharY += yChange
DISPLAYSURF.blit(mainChar, (mainCharX, mainCharY)) # Load character
pygame.display.update() #update window
fpsClock.tick(FPS) # FPS goes always after update
如果一次按下向上箭头,这将很好地工作,但是如果不释放它,则继续在循环中执行yChange-当然根本不需要这样做。你能帮我这个忙吗?
import React, { Component } from 'react';
import { Input, Upload , Icon, message} from 'antd';
import Form from '../../components/uielements/form';
import Checkbox from '../../components/uielements/checkbox';
import Button from '../../components/uielements/button';
import Notification from '../../components/notification';
import { adalApiFetch } from '../../adalConfig';
const FormItem = Form.Item;
class RegisterTenantForm extends Component {
constructor(props) {
super(props);
this.state = {TenantId: '', TenantUrl: '', CertificatePassword: '', confirmDirty: false, loading: false, buttondisabled: true };
this.handleChangeTenantUrl = this.handleChangeTenantUrl.bind(this);
this.handleChangeCertificatePassword = this.handleChangeCertificatePassword.bind(this);
this.handleChangeTenantId= this.handleChangeTenantId.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleupload = this.handleupload.bind(this);
this.handleTenantIdValidation = this.handleTenantIdValidation.bind(this);
this.handleTenantAdminUrl = this.handleTenantAdminUrl.bind(this);
};
handleChangeTenantUrl(event){
this.setState({TenantUrl: event.target.value});
}
handleChangeCertificatePassword(event){
this.setState({CertificatePassword: event.target.value});
}
handleChangeTenantId(event){
this.setState({TenantId: event.target.value});
}
beforeUpload(file) {
const isJPG = file.type === 'image/jpeg';
if (!isJPG) {
message.error('You can only upload JPG file!');
}
}
handleupload(info){
//let files = e.target.files;
if (info.file.status === 'uploading') {
this.setState({ loading: true });
return;
}
if (info.file.status === 'done') {
this.setState({ loading: false });
this.setState({ 'selectedFile': info.file });
}
}
handleTenantIdValidation(rule, value, callback){
const form = this.props.form;
var re = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
if (!form.getFieldValue('tenantid').match(re)) {
callback('Tenant id is not correctly formated id');
}
else {
callback();
}
}
handleTenantAdminUrl(rule, value, callback){
const form = this.props.form;
var re = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/i;
if (!form.getFieldValue('tenantadminurl').match(re)) {
callback('Tenant Url is not correctly formated id');
}
else {
callback();
}
}
handleSubmit(e){
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
/*Notification(
'success',
'Received values of form',
JSON.stringify(values)
);*/
let data = new FormData();
//Append files to form data
data.append("model", JSON.stringify({ "TenantId": this.state.TenantId, "TenantUrl": this.state.TenantUrl, "CertificatePassword": this.state.CertificatePassword }));
//data.append("model", {"TenantId": this.state.TenantId, "TenantUrl": this.state.TenantUrl, "TenantPassword": this.state.TenantPassword });
let files = this.state.selectedFile;
for (let i = 0; i < files.length; i++) {
data.append("file", files[i], files[i].name);
}
const options = {
method: 'put',
body: data,
config: {
headers: {
'Content-Type': 'multipart/form-data'
}
}
};
adalApiFetch(fetch, "/Tenant", options)
.then(response => response.json())
.then(responseJson => {
if (!this.isCancelled) {
this.setState({ data: responseJson });
}
})
.catch(error => {
console.error(error);
});
}
});
}
render() {
const uploadButton = (
<div>
<Icon type={this.state.loading ? 'loading' : 'plus'} />
<div className="ant-upload-text">Upload</div>
</div>
);
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 6 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 14 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 14,
offset: 6,
},
},
};
return (
<Form onSubmit={this.handleSubmit}>
<FormItem {...formItemLayout} label="Tenant Id" hasFeedback>
{getFieldDecorator('tenantid', {
rules: [
{
required: true,
message: 'Please input your tenant id',
},
{
validator: this.handleTenantIdValidation
}],
})(<Input name="tenantid" id="tenantid" onChange={this.handleChangeTenantId}/>)}
</FormItem>
<FormItem {...formItemLayout} label="Certificate Password" hasFeedback>
{getFieldDecorator('certificatepassword', {
rules: [
{
required: true,
message: 'Please input your password!',
}
],
})(<Input type="password" name="certificatepassword" id="certificatepassword" onChange={this.handleChangeCertificatePassword}/>)}
</FormItem>
<FormItem {...formItemLayout} label="Tenant admin url" hasFeedback>
{getFieldDecorator('tenantadminurl', {
rules: [
{
required: true,
message: 'Please input your tenant admin url!',
},
{
validator: this.handleTenantAdminUrl
}],
})(<Input name="tenantadminurl" id="tenantadminurl" onChange={this.handleChangeTenantUrl} />)}
</FormItem>
<FormItem {...formItemLayout} label="Certificate File">
<Upload onChange={this.handleupload} beforeUpload={this.beforeUpload}>
<Button >
<Icon type="upload" /> Click to Upload
</Button>
</Upload>
</FormItem>
<FormItem {...tailFormItemLayout}>
<Button type="primary" htmlType="submit" disabled={this.state.buttondisabled}>
Register tenant
</Button>
</FormItem>
</Form>
);
}
}
const WrappedRegisterTenantForm = Form.create()(RegisterTenantForm);
export default WrappedRegisterTenantForm;
答案 0 :(得分:3)
如果您只希望播放器每次上压能够跳10个“单位”然后停在原处,则可以在将yChange添加到mainCharY之后,将每帧yChange设置为0。
但是,如果您正在寻找一个更强大的跳跃系统(按下按钮,播放器向上移动几帧,然后停下来然后跌倒),则需要更多。
给您一个想法:如果您在每帧的末尾有一些逻辑来检查mainCharY> 0(玩家不在地面上),并且如果是,则从yChange中减去一些数字(就像重力在拉动)他们下来)?
在上述情况下,您的代码应避免重复按下新闻的问题。仅测试(mainCharY> 0)而不是使用isJumping变量可能会更容易。
答案 1 :(得分:1)
我认为pygame可能根本不会错过关键事件。
我认为问题在于您没有在任何地方将isJumping
设置为false,这会在首次按下后永远停止更改yChange
。如果我正确地解释了这一点,那么以下代码应该可以工作:
if event.type == pygame.KEYDOWN:
... # Your other code
if event.key == pygame.K_UP and not isJumping: # "== False" is not necessary
yChange -= 10
isJumping = True
if event.type == pygame.KEYUP:
... # Your other code
if event.key == pygame.K_UP and isJumping:
yChange = 0
isJumping = False # <-- This is the addition to the code
要记住的一件事是,这种跳跃系统看起来不会很自然。期待@SamHolloway的答案以对此进行更多的澄清。
答案 2 :(得分:1)
似乎您误解了事件队列和事件循环的工作方式。当您按下一个键时,单个pygame.KEYDOWN
事件将被添加到事件队列中。调用pygame.event.get
将清空事件队列,并将所有事件放入一个列表中,并使用for循环对其进行迭代:for event in pygame.event.get():
。这意味着pygame不知道您仍在按住该键,它只会看到您已按下UP一次。它还将注意到您释放了密钥并将一个pygame.KEYUP
事件添加到队列中。
在您的情况下,按UP键会将yChange
变量减小为-10
。在while循环中,mainCharY
每帧将减少-10
,并且字符将向上移动。释放键后,yChange
将重置为0
,并且播放器角色将停止。
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
yChange = 0
要在游戏中实现跳跃,您应该添加一个重力常数,并在每帧的y速度中添加该常数以向下加速。当角色接触地面时,将y速度设置为0,并将变量(on_ground
或类似的变量)设置为True
,以便您知道玩家可以跳跃。当玩家按下跳转键时,您可以将y速度设置为负值,并且精灵将开始向上移动,直到重力再次将他拉低。这是complete example。