我在C#中创建一个游戏 [英] I am creating a game in C#

查看:73
本文介绍了我在C#中创建一个游戏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个picturebox1,宽度为53656像素,高度为1080像素,picturebox2为卡通图像。我试图通过在后台缓慢移动picturebox1图像来移动卡通图像。卡通图像是透明的,背景中有picturebox1。当我移动卡通图像(picturebox2)时,它是缓慢的,图像不断重复,卡通图像背景无法跟上更大的picturebox1图像。这是我的代码:



使用System;

使用System.Collections.Generic;

使用System.ComponentModel;

使用System.Data;

使用System.Drawing;

使用System.Linq;

使用System.Text;

使用System.Threading.Tasks ;

使用System.Windows.Forms;



名称空间BackgroundGameScenery

{

公共部分类Form1:表格

{

public Form1()

{

InitializeComponent(); < br $>
}



private void Form1_Load(object sender,EventArgs e)

{

pictureBox2.Parent = pictureBox1;

pictureBox2.BackColor = Color.Transparen t;



pictureBox2.Location = new Point(240,700);

this.pictureBox2.Dock = DockStyle.None;



}



private void timer1_Tick(object sender,EventArgs e)

{



}



private void Form1_KeyPress(对象发送者,KeyPressEventArgs e)

{



}



private void Form1_KeyDown(对象发送者,KeyEventArgs e)

{

if(e.KeyCode == Keys.Right)

{

pictureBox2.Location = new Point(pictureBox2.Location .X + 40,pictureBox2.Location.Y + 0);

//pictureBox2.Left + = 45;

pictureBox1.Left - = 10;

//pictureBox2.Refresh();



pictureBo x1.Refresh();

//this.Refresh();

}

if(e.KeyCode == Keys.Left)

{

pictureBox2.Location = new Point(pictureBox2.Location.X - 40,pictureBox2.Location.Y + 0);

/ /pictureBox2.Left - = 45;

pictureBox1.Left + = 10;

//pictureBox2.Refresh();

pictureBox1.Refresh ();

//this.Refresh();

}

}

}

}

I have a picturebox1 that is 53656px in width and 1080px in height and picturebox2 that is a cartoon image. I am trying to move the cartoon image with moving the picturebox1 image slowly in the background. The cartoon image is transparent with picturebox1 in the background. When I move the cartoon image(picturebox2) it is sluggish and the image keeps repeating and the cartoon image background has trouble keeping up with the larger picturebox1 image.Here is my code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BackgroundGameScenery
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
pictureBox2.Parent = pictureBox1;
pictureBox2.BackColor = Color.Transparent;

pictureBox2.Location = new Point(240, 700);
this.pictureBox2.Dock = DockStyle.None;

}

private void timer1_Tick(object sender, EventArgs e)
{

}

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{

}

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Right)
{
pictureBox2.Location = new Point(pictureBox2.Location.X + 40, pictureBox2.Location.Y + 0);
//pictureBox2.Left += 45;
pictureBox1.Left -= 10;
//pictureBox2.Refresh();

pictureBox1.Refresh();
//this.Refresh();
}
if (e.KeyCode == Keys.Left)
{
pictureBox2.Location = new Point(pictureBox2.Location.X - 40, pictureBox2.Location.Y + 0);
//pictureBox2.Left -= 45;
pictureBox1.Left += 10;
//pictureBox2.Refresh();
pictureBox1.Refresh();
//this.Refresh();
}
}
}
}

推荐答案

不要使用PictureBoxes。期间。



你正在使用MASSIVE PictureBox控件的事实是你的代码放慢了这么多,它无法使用。您应该直接在表单的表面上绘制场景,而不是依赖于从未设计用于支持游戏的控件。
Do NOT use PictureBoxes. Period.

The fact that you're using MASSIVE PictureBox controls is what's slowing your code down so much it's unusable. You should be drawing your scene yourself directly on the surface of the form, not relying on controls that were never designed to support a game.


这非常非常糟糕。第一个错误是使用 PictureBox 。这个真正冗余的控件,在一些最简单的情况下很有用,已成为许多初学者的真正诅咒。它没有任何帮助,只会浪费你的开发时间,吃掉一些资源,影响性能。请查看我过去的答案:

在其中附加图片图片框 [ ^ ],

画一个矩形C# [ ^ ],

如何从旧图纸中清除面板 [ ^ ]。



有关图形渲染的更多细节,请看看我过去的答案:

什么样的俏皮方法是Paint? (DataGridViewImageCell.Paint(...)) [ ^ ],

线程和动画:如何加速我的vb.net应用程序? [ ^ ],

在面板上捕获图纸 [ ^ ],

mdi子窗体之间的绘制线 [ ^ ]。



另一个问题是使用计时器。我不知道你尝试使用什么计时器,但从不使用 System.Windows.Forms.Timer 。它的准确性非常低,即使是近似周期也无法提供任何东西。其他计时器更好,但需要UI线程调用(请参见下文)。但计时器通常是有问题的。您是否曾尝试处理下一个计时器事件未处理上一个事件时的情况?考虑一下。



使用 System.Diagnostics.Stopwatch <渲染实时时,最好使用单独的线程/ code>。即使帧渲染的时刻可能不是以规则的间隔出现,动画看起来也会非常流畅。此外,渲染应该使用双缓冲



基本上,你的线程工作在物理数据和状态机的状态。然后线程通知UI线程进行渲染。您不能从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke()

使用Treeview扫描仪和MD5的问题



另请参阅有关线程的更多参考资料:

如何在vb.net中的另一个线程上运行keydown事件

在启用禁用+多线程后控制事件未触发;

参见:主线程上的.NET事件 [ ^ ]。



-SA
This is very, very bad. First mistake is using PictureBox. This really redundant control, useful in some simplest cases, has became a real curse of so many beginners. It does not help anything, only will waste your development time and eat up some resources, compromise performance. Please see my past answers:
Append a picture within picturebox[^],
draw a rectangle in C#[^],
How do I clear a panel from old drawing[^].

For further detail on graphics rendering, please see my past answers:
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
threading and animation: How to speed up my vb.net application?[^],
capture the drawing on a panel[^],
Drawing Lines between mdi child forms[^].

Another problem is using the timer. I don't know what timer did you try to use, but never use System.Windows.Forms.Timer. It's accuracy is so low, that it cannot deliver anything even approximately periodic. Other timers are better but will require UI thread invocation (please see below). But timers are generally problematic. Did you ever tried to handle situations when next timer event comes when the previous event is not handled? Just think about it.

It's better to use a separate thread, at the moment of rendering taking real time using System.Diagnostics.Stopwatch. Even though the moment of times at the frame rendering may come not at regular intervals, the animation will look perfectly smooth. Also, rendering should use double buffering.

Basically, your threads work in the "physics" data and states of the state machine. Then the thread notifies the UI thread to do the rendering. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke(),
Problem with Treeview Scanner And MD5.

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net,
Control events not firing after enable disable + multithreading;
see also: .NET event on main thread[^].

—SA


这篇关于我在C#中创建一个游戏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆