Related
I make an game 2D in Unity. My game looks different on the phone. I would the gameobject come to the scene episodic. When I test it on the computer, there is not trouble. But when I test on the phone, the process is repeating.
Code :
for(kacxgiti = 0; kacxgiti < 91; kacxgiti++){
karbayv = karbay.transform.position;
if(kacxgiti < 90){
karbay.transform.position = new Vector3(karbayv.x - 0.1f, karbayv.y, karbayv.z);
kacxgiti = kacxgiti + 1;
yield return new WaitForSeconds(0.05f);
}else{
kamyongel();
}
}
Full Code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using GoogleMobileAds.Api;
using System;
public class karhareket : MonoBehaviour
{
public GameObject karbay;
Vector3 karbayv;
int kacxgiti;
public static int kamyongeli, kamyongidi;
public GameObject kamyon;
Vector3 kamyonv, kamyonvv;
int kamyonxgiti;
int kamyoncikari;
public Button subebtn;
public Text guntext;
int guni, gunfonti, gunbuyuti, kardurduri;
public Sprite[] musteris;
int musterigeli, musterixgel, mustericikari;
public GameObject musteri;
Vector3 musteriv, musterivv;
public Text paratext;
string gecisid;
InterstitialAd gecisreklam;
int ilkgunyazii;
// Start is called before the first frame update
void Start()
{
ilkgunyazii = 1;
gecisid = "ca-app-pub-6761789303172472/5658205887";
this.gecisreklam = new InterstitialAd(gecisid);
AdRequest request = new AdRequest.Builder().Build();
this.gecisreklam.LoadAd(request);
this.gecisreklam.OnAdClosed += reklamkapatinca;
this.gecisreklam.OnAdFailedToLoad += reklamkapatinca;
if(PlayerPrefs.HasKey("para")){
paratext.text = PlayerPrefs.GetInt("para") + "$";
}else{
PlayerPrefs.SetInt("para", 100);
PlayerPrefs.Save();
paratext.text = "100$";
}
kamyongeli = 1;
kamyoncikari = 0;
kardurduri = 0;
musterigeli = 1;
if(PlayerPrefs.GetInt("mustericikar") == 1){
ilkgunyazii = 0;
guntext.text = "";
musteri.GetComponent<SpriteRenderer>().sprite = musteris[PlayerPrefs.GetInt("musteriid")];
PlayerPrefs.DeleteKey("musteriid");
PlayerPrefs.DeleteKey("mustericikar");
kamyon.gameObject.SetActive(false);
musterigeli = 0;
kamyongeli = 0;
kardurduri = 1;
guntext.gameObject.SetActive(false);
musterigidivergari();
}
while(kamyongidi == 1 || PlayerPrefs.GetInt("kamyoncikar") == 1){
int musterid = UnityEngine.Random.Range(0, 20);
musteri.GetComponent<SpriteRenderer>().sprite = musteris[musterid];
PlayerPrefs.SetInt("musteriid", musterid);
PlayerPrefs.Save();
ilkgunyazii = 0;
PlayerPrefs.DeleteKey("kamyoncikar");
kamyongeli = 0;
kardurduri = 1;
kamyongidivergari();
guntext.gameObject.SetActive(false);
//gun ve karakter ilerleme olmasın
break;
}
if(kardurduri == 0){
kamyongeli = 0;
karbayv = karbay.transform.position;
//InvokeRepeating("pozisyonayarla", 0, 0.05f);
for(kacxgiti = 0; kacxgiti < 91; kacxgiti++){
karbayv = karbay.transform.position;
if(kacxgiti < 90){
karbay.transform.position = new Vector3(karbayv.x - 0.1f, karbayv.y, karbayv.z);
karbayv = new Vector3(karbayv.x - 0.1f, karbayv.y, karbayv.z);
kacxgiti = kacxgiti + 1;
yield return new WaitForSeconds(0.05f);
}else{
kamyongelivergari();
break;
}
}
}else{
karbay.transform.position = new Vector3(-4, -1, 0);
}
while(kamyongeli == 1){
InvokeRepeating("kamyongelsin", 0, 0.03f);
break;
}
subebtn.onClick.AddListener(subetik);
if(PlayerPrefs.HasKey("gun")){
guni = PlayerPrefs.GetInt("gun");
}else{
PlayerPrefs.SetInt("gun", 1);
PlayerPrefs.Save();
guni = 1;
}
if(ilkgunyazii == 1){
gunfonti = 20;
gunbuyuti = 1;
guntext.text = "Day " + guni.ToString();
InvokeRepeating("guntextayarla", 0, 0.02f);
}
}
void guntextayarla(){
if(gunbuyuti == 0){
guntext.fontSize = gunfonti;
gunfonti--;
}else if(gunbuyuti == 1){
guntext.fontSize = gunfonti;
gunfonti++;
if(gunfonti == 61){
gunbuyuti = 0;
}
}
}
void musterigelsin(){
musteriv = musteri.transform.position;
if(musterixgel < 145){
musteri.transform.position = new Vector3(musteriv.x - 0.1f, musteriv.y, musteriv.z);
musterixgel++;
}else{
musterigeli = 0;
SceneManager.LoadScene("malsat");
}
}
void musterigitsin(){
musterivv = musteri.transform.position;
if(mustericikari < 575){
musteri.transform.position = new Vector3(musterivv.x - 0.1f, musterivv.y, musterivv.z);
mustericikari++;
if(mustericikari == 165){
gunbittiyaziayarla();
}
}
}
void kamyongelivergari(){
//CancelInvoke("pozisyonayarla");
kamyongeli = 1;
//kardurduri = 1;
InvokeRepeating("kamyongelsin", 0, 0.05f);
}
void reklamgoster(){
if(gecisreklam.IsLoaded()){
gecisreklam.Show();
}else{
reklamkapatincaa();
}
}
public void reklamkapatinca(object sender, EventArgs args){
SceneManager.LoadScene("manav");
}
public void reklamkapatincaa(){
SceneManager.LoadScene("manav");
}
void gunbittextayarla(){
if(gunbuyuti == 0){
guntext.fontSize = gunfonti;
gunfonti--;
}else if(gunbuyuti == 1){
guntext.fontSize = gunfonti;
gunfonti++;
if(gunfonti == 41){
gunbuyuti = 0;
PlayerPrefs.SetInt("gun", PlayerPrefs.GetInt("gun") + 1);
PlayerPrefs.Save();
reklamgoster();
CancelInvoke("gunbittextayarla");
}
}
}
void gunbittiyaziayarla(){
guntext.text = "Day " + PlayerPrefs.GetInt("gun") + " Finished";
guntext.gameObject.SetActive(true);
guntext.text = "Day " + PlayerPrefs.GetInt("gun") + " Finished";
gunfonti = 20;
gunbuyuti = 1;
InvokeRepeating("gunbittextayarla", 0, 0.02f);
}
void subetik(){
SceneManager.LoadScene("subeler");
}
void pozisyonayarla(){
karbayv = karbay.transform.position;
if(kacxgiti < 90){
karbay.transform.position = new Vector3(karbayv.x - 0.1f, karbayv.y, karbayv.z);
kacxgiti++;
}else{
kamyongelivergari();
}
}
void kamyongelsin(){
kamyonv = kamyon.transform.position;
if(kamyonxgiti < 125){
kamyon.transform.position = new Vector3(kamyonv.x - 0.1f, kamyonv.y, kamyonv.z);
kamyonxgiti++;
}else{
kamyongeli = 0;
SceneManager.LoadScene("malal");
CancelInvoke("kamyongelsin");
}
}
void kamyongitsin(){
kamyongidi = 0;
kamyonvv = kamyon.transform.position;
if(kamyoncikari < 300){
kamyon.transform.position = new Vector3(kamyonvv.x - 0.1f, kamyonvv.y, kamyonvv.z);
kamyoncikari++;
if(kamyoncikari == 150){
Debug.Log("geldi");
musterigelivergari();
}
}else{
CancelInvoke("kamyongitsin");
}
}
void musterigelivergari(){
InvokeRepeating("musterigelsin", 0, 0.03f);
}
void musterigidivergari(){
musteri.transform.position = new Vector3(0f, -1.9f, 0f);
InvokeRepeating("musterigitsin", 0, 0.05f);
}
void kamyongidivergari(){
kamyon.transform.position = new Vector3(0f, -3f, kamyon.transform.position.z);
InvokeRepeating("kamyongitsin", 0, 0.05f);
}
//kamyongidi 1 olunca kamyonu gönder
// Update is called once per frame
void Update()
{
/*if(kamyongeli == 1){
InvokeRepeating("kamyongelsin", 0, 0.05f);
}*/
/*if(kamyongidi == 1 || PlayerPrefs.GetInt("kamyoncikar") == 1){
kamyongeli = 0;
kamyongidivergari();
PlayerPrefs.SetInt("kamyoncikar", 0);
PlayerPrefs.Save();
//kamyongidi = 0;
}else if(kamyongeli == 1){
InvokeRepeating("kamyongelsin", 0, 0.05f);
kamyongeli = 0;
}*/
}
}
In pc :
https://drive.google.com/file/d/1IaOMyP4bzOopaQCjBtOBV-KBYBflIB_f/view?usp=drivesdk
In phone :
https://drive.google.com/file/d/1IcPNvg7OjCerzFKc8M12LrO8B-BKyWUC/view?usp=drivesdk
How I can resolve this problem?
I have a problem with my code, check the code down below, so you understand which section i'm talking about!
I'm trying to add new block levels when "block.Count == 1", you know when all my blocks are destroyed by the ball. I want it to start a new level with a different block path. When I have:
else if (block.Count == 1 && block2.Count == 1)
{
spriteBatch.Draw(gameover_texture, gameover_rect, Color.White);
}
It doesn't draw out my gameover_texture, when are blocks are gone?
(Sorry about my bad english)
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont spritefont;
Texture2D paddle_texture;
Texture2D ball_texture;
Texture2D blockred_texture;
Texture2D blockgreen_texture;
Texture2D gameover_texture;
Rectangle paddle_rect;
Rectangle ball_rect;
Rectangle blockred_rect;
Rectangle blockgreen_rect;
Rectangle gameover_rect;
Vector2 paddle_speed;
Vector2 ball_speed;
Random random;
StreamReader sr;
StreamWriter sw;
int lives = 3;
int points = 0;
int highscore;
int counter = 0;
int seconds = 0;
List<Rectangle> block = new List<Rectangle>();
List<Rectangle> block2 = new List<Rectangle>();
bool Start = false;
bool holdingleft = false;
bool holdingright = false;
bool resetballspeed = false;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 760;
graphics.PreferredBackBufferHeight = 620;
}
protected override void Initialize()
{
random = new Random();
paddle_speed.X = 6f;
ball_speed.X = random.Next(-1, 1);
ball_speed.Y = 7f;
sr = new StreamReader("highscore.txt");
highscore = int.Parse(sr.ReadLine());
sr.Close();
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spritefont = Content.Load<SpriteFont>("Fonts/Myfont");
paddle_texture = Content.Load<Texture2D>("Pics/linje");
ball_texture = Content.Load<Texture2D>("Pics/boll");
blockgreen_texture = Content.Load<Texture2D>("Pics/block-grön");
blockred_texture = Content.Load<Texture2D>("Pics/block-röd");
gameover_texture = Content.Load<Texture2D>("Pics/GameOver");
paddle_rect = new Rectangle((Window.ClientBounds.Width - paddle_texture.Width) / 2, 580, paddle_texture.Width, paddle_texture.Height);
ball_rect = new Rectangle((Window.ClientBounds.Width - ball_texture.Width) / 2, 556, ball_texture.Width, ball_texture.Height);
gameover_rect = new Rectangle((Window.ClientBounds.Width / 2) - (gameover_texture.Width / 2), (Window.ClientBounds.Height / 2) - gameover_texture.Height / 2, gameover_texture.Width, gameover_texture.Height);
block.Add(blockgreen_rect);
block2.Add(blockred_rect);
for (int i = 1; i < 2; i++)
{
for (int g = 1; g < 3; g++)
{
block2.Add(new Rectangle((g * 63) - 60, (i * 40), blockred_texture.Width, blockred_texture.Height));
}
}
for (int i = 1; i < 2; i++)
{
for (int g = 1; g < 3; g++)
{
block.Add(new Rectangle((g * 63) - 60, (i * 20) + 40, blockgreen_texture.Width, blockgreen_texture.Height));
}
}
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if (Start == true) //kolla om "Start == true",
{
ball_rect.X += (int)ball_speed.X;
ball_rect.Y += (int)ball_speed.Y;
}
if (Start == false)
{
ball_rect.X = paddle_rect.X + ((paddle_rect.Width / 2) - (ball_texture.Width / 2));
}
if (ball_rect.X > Window.ClientBounds.Width - ball_texture.Width || ball_rect.X < 0)
ball_speed.X *= -1;
if (ball_rect.Y > Window.ClientBounds.Height - ball_texture.Height || ball_rect.Y < 0)
ball_speed.Y *= -1;
if (ball_rect.Y > Window.ClientBounds.Height - ball_texture.Height)
{
lives -= 1;
Start = false;
ball_rect.X = (Window.ClientBounds.Width - ball_texture.Width) / 2;
ball_rect.Y = 556;
paddle_rect.X = (Window.ClientBounds.Width - paddle_texture.Width) / 2;
paddle_rect.Y = 580;
}
KeyboardState ks = Keyboard.GetState();
if (ks.IsKeyDown(Keys.Left))
{
paddle_rect.X -= (int)paddle_speed.X;
holdingleft = true;
}
else if (ks.IsKeyDown(Keys.Right))
{
paddle_rect.X += (int)paddle_speed.X;
holdingright = true;
}
else if (ks.IsKeyDown(Keys.Space))
{
Start = true;
}
else if (ks.Equals(new KeyboardState()))
{
resetballspeed = true;
}
if (paddle_rect.X > Window.ClientBounds.Width - paddle_rect.Width)
paddle_rect.X = (Window.ClientBounds.Width - paddle_rect.Width);
if (paddle_rect.X < 0)
paddle_rect.X = 0;
if (paddle_rect.Intersects(ball_rect))
{
ball_speed.Y *= -1;
ball_rect.Y += (int)ball_speed.Y;
if (holdingleft == true)
{
ball_speed.X -= 3;
}
else if (holdingright == true)
{
ball_speed.X += 3;
}
else if (resetballspeed == true)
{
ball_speed.X = 1;
}
}
if (points == highscore)
{
sw = new StreamWriter("highscore.txt");
sw.WriteLine(points);
sw.Close();
}
for (int j = 1; j < block.Count; j++)
{
if (ball_rect.Intersects(block[j]))
{
ball_speed.Y *= -1;
points += 1;
block.RemoveAt(j);
if (points > 9)
{
paddle_rect.Width = 60;
}
if (points > highscore)
{
highscore = points;
}
}
}
for (int k = 1; k < block2.Count; k++)
{
if (ball_rect.Intersects(block2[k]))
{
ball_speed.Y *= -1;
points += 5;
block2.RemoveAt(k);
if (points > 9)
{
paddle_rect.Width = 60;
}
if (points > highscore)
{
highscore = points;
}
}
}
holdingleft = false;
holdingright = false;
counter++;
if (counter == 60)
{
seconds++;
counter = 0;
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
// TODO: Add your drawing code here
spriteBatch.Begin();
if (lives > 0)
{
spriteBatch.Draw(ball_texture, ball_rect, Color.White);
spriteBatch.Draw(paddle_texture, paddle_rect, Color.White);
spriteBatch.DrawString(spritefont, "Lives left: " + lives, Vector2.Zero, Color.White);
spriteBatch.DrawString(spritefont, "Points: " + points, new Vector2(350, 0), Color.White);
spriteBatch.DrawString(spritefont, "Timer: " + seconds, new Vector2(350, 600), Color.White);
spriteBatch.DrawString(spritefont, "Highscore: " + highscore, new Vector2(660, 0), Color.White);
foreach (Rectangle g in block)
{
spriteBatch.Draw(blockgreen_texture, g, Color.White);
}
foreach (Rectangle t in block2)
{
spriteBatch.Draw(blockred_texture, t, Color.White);
}
}
else if (block.Count == 1 && block2.Count == 1)
{
spriteBatch.Draw(gameover_texture, gameover_rect, Color.White);
}
else if (lives == 0)
{
spriteBatch.Draw(gameover_texture, gameover_rect, Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
Fixed the problem now, by putting the else if-statement inside "if (lives > 0)"
I'm building a game using xna and I've created a terrain using VertexElementNormalTexture. I understand I can add position, the normal and texture coordinates to the vertex element but is there anyway to add which texture I want to use. I'm testing it on my Lumia phone so it's being built without the use of custom shaders because they're unsupported by the phone making most of the tutorials on the web out of date. I believe the basiceffects only support one texture per effect so if I make a number of effects how do I get the vertex to know which effect to use? the grasseffect, watereffect, etc.
The code I've got so far is below.
Thank you.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using Microsoft.Devices.Sensors;
namespace WindowsPhoneGame2
{
public class Game1 : Microsoft.Xna.Framework.Game
{
#region // Variables
public struct VertexPositionColorNormal
{
public Vector3 Position;
public Color Color;
public Vector3 Normal;
public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
(
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3, VertexElementFormat.Color, VertexElementUsage.Color, 0),
new VertexElement(sizeof(float) * 3 + 4, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0)
);
}
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
RasterizerState rasterizerState;
// terrain
BasicEffect grassEffect;
Texture2D grassTexture;
BasicEffect waterEffect;
Texture2D waterTexture;
VertexDeclaration vertexDeclaration;
VertexPositionNormalTexture[] vertices;
short[] indices;
VertexBuffer myVertexBuffer;
IndexBuffer myIndexBuffer;
private float[,] heightData;
private int terrainWidth;
private int terrainLength;
int nScale = 16;
Vector3 terrainPosition;
Texture2D heightMap;
Matrix viewMatrix;
Matrix projectionMatrix;
Matrix worldMatrix;
// aircraft model
private Model aircraftModel;
private Vector3 aircraftPosition;
Matrix aircraftMatrix;
// shell model
private Model shellModel;
private Vector3 bulletPosition;
Matrix bulletMatrix;
bool blBulletFiring;
private Vector3 torpedoPosition;
Matrix torpedoMatrix;
bool blTorpedoFiring;
float nTorpedoScale;
// display
private SpriteFont font;
float nHeightData;
int nBullets = 0;
int nTorpedoes = 0;
// tilt gesture
private float rollAngle;
private float pitchAngle;
private float yawAngle;
Accelerometer accelerometer;
private const int _num = 5;
private double[] _y = new double[_num];
private int _index = 0;
private const int _num2 = 5;
private double[] _y2 = new double[_num2];
private int _index2 = 0;
Texture2D explosionTexture;
List<ParticleData> particleList = new List<ParticleData>();
public struct ParticleData
{
public float BirthTime;
public float MaxAge;
public Vector2 OrginalPosition;
public Vector2 Accelaration;
public Vector2 Direction;
public Vector2 Position;
public float Scaling;
public Color ModColor;
}
Random random = new Random();
#endregion
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
TouchPanel.EnabledGestures = GestureType.Tap | GestureType.Hold;
loadTextures();
loadAccelerometer();
loadCamera();
loadEffect();
loadTerrain();
}
protected override void UnloadContent()
{
}
private void loadTextures()
{
aircraftModel = Content.Load<Model>("Ship");
shellModel = Content.Load<Model>("Shell");
explosionTexture = Content.Load<Texture2D>("explosion");
heightMap = Content.Load<Texture2D>("heightmap");
grassTexture = Content.Load<Texture2D>("Grass");
waterTexture = Content.Load<Texture2D>("Water");
font = Content.Load<SpriteFont>("DisplayText");
}
private void loadAccelerometer()
{
rollAngle = 0;
if (accelerometer == null)
{
accelerometer = new Accelerometer();
accelerometer.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);
accelerometer.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(accelerometer_CurrentValueChanged);
}
accelerometer.Start();
}
private void loadCamera()
{
aircraftPosition = new Vector3(heightMap.Width * nScale * 2 / 2, 0, 400);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, graphics.GraphicsDevice.Viewport.AspectRatio, 10.0f, 8000.0f);
worldMatrix = Matrix.CreateTranslation(0, 0, 0);
terrainPosition = new Vector3(0, 0, 0);
}
private void loadEffect()
{
//grass effect
grassEffect = new BasicEffect(GraphicsDevice);
//grassEffect.VertexColorEnabled = true;
grassEffect.LightingEnabled = true; // Turn on the lighting subsystem.
grassEffect.DirectionalLight0.DiffuseColor = new Vector3(0.1f, 0.1f, 0.1f);
grassEffect.DirectionalLight0.Direction = new Vector3(0, 5, -10);
grassEffect.TextureEnabled = true;
grassEffect.Texture = grassTexture;
//water effect
waterEffect = new BasicEffect(GraphicsDevice);
waterEffect.LightingEnabled = true; // Turn on the lighting subsystem.
waterEffect.DirectionalLight0.DiffuseColor = new Vector3(0.1f, 0.1f, 0.1f);
waterEffect.DirectionalLight0.Direction = new Vector3(0, 5, -10);
waterEffect.TextureEnabled = true;
waterEffect.Texture = waterTexture;
}
private void loadTerrain()
{
LoadHeightData();
SetUpVertices();
SetUpIndices();
CalculateNormals();
CopyToBuffers();
}
private void LoadHeightData()
{
terrainWidth = heightMap.Width;
terrainLength = heightMap.Height;
Color[] heightMapColors = new Color[terrainWidth * terrainLength];
heightMap.GetData(heightMapColors);
heightData = new float[terrainWidth, terrainLength];
for (int x = 0; x < terrainWidth; x++)
for (int y = 0; y < terrainLength; y++)
heightData[x, y] = heightMapColors[x + y * terrainWidth].R / 5.0f;
}
private void SetUpVertices()
{
vertices = new VertexPositionNormalTexture[terrainWidth * terrainLength];
for (int x = 0; x < terrainWidth; x++)
{
for (int y = 0; y < terrainLength; y++)
{
vertices[x + y * terrainWidth].Position = new Vector3(x * nScale * 2, y * nScale, heightData[x, y] * nScale) + terrainPosition;
}
}
}
private void SetUpIndices()
{
indices = new short[(terrainWidth - 1) * (terrainLength - 1) * 6];
int counter = 0;
for (int y = 0; y < terrainLength - 1; y++)
{
for (int x = 0; x < terrainWidth - 1; x++)
{
short lowerLeft = (short)(x + y * terrainWidth);
short lowerRight = (short)((x + 1) + y * terrainWidth);
short topLeft = (short)(x + (y + 1) * terrainWidth);
short topRight = (short)((x + 1) + (y + 1) * terrainWidth);
indices[counter++] = topLeft;
indices[counter++] = lowerRight;
indices[counter++] = lowerLeft;
indices[counter++] = topLeft;
indices[counter++] = topRight;
indices[counter++] = lowerRight;
}
}
}
private void CalculateNormals()
{
for (int i = 0; i < vertices.Length; i++)
vertices[i].Normal = new Vector3(0, 0, 0);
for (int i = 0; i < indices.Length / 3; i++)
{
int index1 = indices[i * 3];
int index2 = indices[i * 3 + 1];
int index3 = indices[i * 3 + 2];
Vector3 side1 = vertices[index1].Position - vertices[index3].Position;
Vector3 side2 = vertices[index1].Position - vertices[index2].Position;
Vector3 normal = Vector3.Cross(side1, side2);
vertices[index1].Normal += normal;
vertices[index2].Normal += normal;
vertices[index3].Normal += normal;
}
for (int i = 0; i < vertices.Length; i++)
vertices[i].Normal.Normalize();
}
private void CopyToBuffers()
{
myVertexBuffer = new VertexBuffer(graphics.GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
myVertexBuffer.SetData(vertices);
myIndexBuffer = new IndexBuffer(graphics.GraphicsDevice, typeof(short), indices.Length, BufferUsage.WriteOnly);
myIndexBuffer.SetData(indices);
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// Adjust camera position
viewMatrix = Matrix.CreateLookAt(new Vector3(aircraftPosition.X, aircraftPosition.Y - 10, aircraftPosition.Z + 5), new Vector3(aircraftPosition.X, aircraftPosition.Y + 5, aircraftPosition.Z ), new Vector3(0, 1, 0));
// Adjust aircraft position
aircraftMatrix = Matrix.CreateRotationY(rollAngle) * Matrix.CreateRotationX(pitchAngle) * Matrix.CreateRotationZ(yawAngle) * Matrix.CreateTranslation(aircraftPosition);
aircraftPosition.Y += 10.0f;
// Check against height data for collision
int x = (int)aircraftPosition.X / (nScale * 2);
int y = ((int)aircraftPosition.Y - (int)terrainPosition.Y) / nScale;
if(y < 128) nHeightData = heightData[(int)x, (int)y];
if (nHeightData > aircraftPosition.Z / nScale)
{
aircraftPosition = new Vector3(terrainWidth * nScale * 2 / 2, 0, 400);
terrainPosition = new Vector3(0, 0, 0);
}
// edit weapons fire positions
if (blBulletFiring)
{
bulletPosition.Y += 20;
fireBullet();
}
if (blTorpedoFiring)
{
if (torpedoPosition.Z > 5)
{
torpedoPosition.Z -= 6;
torpedoPosition.Y += 10;
nTorpedoScale = 0.8f;
}
else
{
torpedoPosition.Y += 16;
nTorpedoScale = 1.5f;
}
fireTorpedo();
}
// detect any gestures
while (TouchPanel.IsGestureAvailable)
{
GestureSample gs = TouchPanel.ReadGesture();
switch (gs.GestureType)
{
case GestureType.Tap:
blBulletFiring = true;
bulletPosition = new Vector3(aircraftPosition.X - 0.05f, aircraftPosition.Y, aircraftPosition.Z);
AddExplosion(new Vector2(gs.Position.X, gs.Position.Y), 12, 80.0f, 1500.0f, gameTime);
// AddExplosion(new Vector2(aircraftPosition.X * -1, aircraftPosition.Y * -1), 12, 80.0f, 1500.0f, gameTime);
break;
case GestureType.Hold:
blTorpedoFiring = true;
torpedoPosition = new Vector3(aircraftPosition.X, aircraftPosition.Y, aircraftPosition.Z);
break;
}
}
if (particleList.Count > 0)
UpdateParticles(gameTime);
base.Update(gameTime);
}
private void UpdateParticles(GameTime gameTime)
{
float now = (float)gameTime.TotalGameTime.TotalMilliseconds;
for (int i = particleList.Count - 1; i >= 0; i--)
{
ParticleData particle = particleList[i];
float timeAlive = now - particle.BirthTime;
if (timeAlive > particle.MaxAge)
{
particleList.RemoveAt(i);
}
else
{
float relAge = timeAlive / particle.MaxAge;
particle.Position = 0.5f * particle.Accelaration * relAge * relAge + particle.Direction * relAge + particle.OrginalPosition;
float invAge = 1.0f - relAge;
particle.ModColor = new Color(new Vector4(invAge, invAge, invAge, invAge));
Vector2 positionFromCenter = particle.Position - particle.OrginalPosition;
float distance = positionFromCenter.Length();
particle.Scaling = (50.0f + distance) / 200.0f;
particleList[i] = particle;
}
}
}
private void AddExplosion(Vector2 explosionPos, int numberOfParticles, float size, float maxAge, GameTime gameTime)
{
for (int i = 0; i < numberOfParticles; i++)
AddExplosionParticle(explosionPos, size, maxAge, gameTime);
}
private void AddExplosionParticle(Vector2 explosionPos, float explosionSize, float maxAge, GameTime gameTime)
{
ParticleData particle = new ParticleData();
particle.OrginalPosition = explosionPos;
particle.Position = particle.OrginalPosition;
particle.BirthTime = (float)gameTime.TotalGameTime.TotalMilliseconds;
particle.MaxAge = maxAge;
particle.Scaling = 0.25f;
particle.ModColor = Color.White;
float particleDistance = (float)random.NextDouble() * explosionSize;
Vector2 displacement = new Vector2(particleDistance, 0);
float angle = MathHelper.ToRadians(random.Next(360));
displacement = Vector2.Transform(displacement, Matrix.CreateRotationZ(angle));
particle.Direction = displacement * 2.0f;
particle.Accelaration = -particle.Direction;
particleList.Add(particle);
}
private void fireBullet()
{
nBullets++;
bulletMatrix = Matrix.CreateScale(0.1f) * Matrix.CreateRotationZ(MathHelper.ToRadians(90)) * Matrix.CreateTranslation(bulletPosition);
if (bulletPosition.Y > aircraftPosition.Y + 200)
{
blBulletFiring = false;
}
}
private void fireTorpedo()
{
nTorpedoes++;
torpedoMatrix = Matrix.CreateScale(nTorpedoScale) * Matrix.CreateRotationZ(MathHelper.ToRadians(90)) * Matrix.CreateTranslation(torpedoPosition);
if (torpedoPosition.Y > aircraftPosition.Y + 1000)
{
blTorpedoFiring = false;
}
}
public void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
_y[_index++] = e.SensorReading.Acceleration.Y;
if (_index >= _num) _index = 0;
double ysum = 0.0;
for (int i = 0; i < _num; i++)
ysum += _y[i];
double x = ysum / _num;
// Cap it at -0.5 and 0.5
if (x > 0.1)
{
if (rollAngle >= -0.9)
{
rollAngle -= 0.05f;
yawAngle += 0.02f;
}
if (aircraftPosition.X >= 5) aircraftPosition.X -= rollAngle * -5;
}
else if (x <= -0.1)
{
if (rollAngle <= 0.9)
{
rollAngle += 0.05f;
yawAngle -= 0.02f;
}
if (aircraftPosition.X <= terrainWidth * nScale * 2 - 6) aircraftPosition.X += rollAngle * 5;
}
else
{
if (rollAngle > 0.05)
{
rollAngle -= 0.05f;
yawAngle += 0.02f;
}
else if (rollAngle < -0.05)
{
rollAngle += 0.05f;
yawAngle -= 0.02f;
}
else
{
rollAngle = 0;
yawAngle = 0;
}
}
_y2[_index2++] = e.SensorReading.Acceleration.X;
if (_index2 >= _num2) _index2 = 0;
double ysum2 = 0.0;
for (int i = 0; i < _num2; i++)
ysum2 += _y2[i];
double x2 = ysum2 / _num2;
// Cap it at -0.5 and 0.5
if (x2 > -0.4)
{
if(pitchAngle >= -0.6) pitchAngle -= 0.025f;
if (aircraftPosition.Z > 6) aircraftPosition.Z -= pitchAngle * -10;
}
else if (x2 <= -0.5)
{
if (pitchAngle <= 0.6) pitchAngle += 0.025f;
if (aircraftPosition.Z <= 500) aircraftPosition.Z += pitchAngle * 10;
}
else
{
if (pitchAngle > 0.05) pitchAngle -= 0.05f;
else if (pitchAngle < -0.05) pitchAngle += 0.05f;
else pitchAngle = 0;
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1.0f, 0);
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
rasterizerState = new RasterizerState();
rasterizerState.FillMode = FillMode.Solid;
rasterizerState.CullMode = CullMode.None;
GraphicsDevice.RasterizerState = rasterizerState;
Vector3 oldPosition = terrainPosition;
loadTerrain();
DrawTerrain();
terrainPosition.Y += nScale * terrainLength - nScale;
loadTerrain();
DrawTerrain();
terrainPosition.Y += nScale * terrainLength - nScale;
loadTerrain();
DrawTerrain();
terrainPosition.Y -= nScale * terrainLength - nScale;
if (aircraftPosition.Y >= terrainPosition.Y)
{ }
else
{
terrainPosition = oldPosition;
}
if (blBulletFiring) DrawBullet(shellModel, bulletMatrix, viewMatrix, projectionMatrix);
if(blTorpedoFiring) DrawTorpedo(shellModel, torpedoMatrix, viewMatrix, projectionMatrix);
DrawAircraft(aircraftModel, aircraftMatrix, viewMatrix, projectionMatrix);
DrawDisplay();
DrawExplosion();
base.Draw(gameTime);
}
private void DrawTerrain()
{
grassEffect.World = worldMatrix;
grassEffect.View = viewMatrix;
grassEffect.Projection = projectionMatrix;
foreach (EffectPass pass in grassEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.Indices = myIndexBuffer;
GraphicsDevice.SetVertexBuffer(myVertexBuffer);
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3);
}
}
private void DrawBullet(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.LightingEnabled = true;
effect.DirectionalLight0.DiffuseColor = new Vector3(0.9f, 0.0f, 0.0f);
effect.DirectionalLight0.Direction = new Vector3(0, 1, -1);
effect.World = world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}
private void DrawTorpedo(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.LightingEnabled = true;
effect.DirectionalLight0.DiffuseColor = new Vector3(0.0f, 0.0f, 0.0f);
effect.DirectionalLight0.Direction = new Vector3(0, 1, -1);
effect.World = world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}
private void DrawAircraft(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
// effect.EnableDefaultLighting();
effect.LightingEnabled = true; // Turn on the lighting subsystem.
effect.DirectionalLight0.DiffuseColor = new Vector3(0.2f, 0.2f, 0.2f);
effect.DirectionalLight0.Direction = new Vector3(0, 5, -10);
//effect.DirectionalLight0.SpecularColor = new Vector3(0, 1, 0); // with green highlights
//effect.AmbientLightColor = new Vector3(0.2f, 0.2f, 0.2f); // Add some overall ambient light.
//effect.EmissiveColor = new Vector3(1, 0, 0); // Sets some strange emmissive lighting. This just looks weird.
effect.World = world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}
private void DrawDisplay()
{
spriteBatch.Begin();
spriteBatch.DrawString(font, "Position: " + aircraftPosition.ToString(), new Vector2(10, 10), Color.Black);
spriteBatch.DrawString(font, "Ground Height: " + nHeightData.ToString(), new Vector2(10, 25), Color.Black);
spriteBatch.DrawString(font, "Bullet Position: " + nBullets.ToString(), new Vector2(10, 40), Color.Black);
spriteBatch.DrawString(font, "Torpedo Position: " + nTorpedoes.ToString(), new Vector2(10, 55), Color.Black);
spriteBatch.End();
}
private void DrawExplosion()
{
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
for (int i = 0; i < particleList.Count; i++)
{
ParticleData particle = particleList[i];
spriteBatch.Draw(explosionTexture, particle.Position, null, particle.ModColor, i, new Vector2(256, 256), particle.Scaling, SpriteEffects.None, 1);
}
spriteBatch.End();
}
}
}
Instead of using a BasicEffect, use a DualTextureEffect. I've never used it before because I don't develop for hone but this is supposed to be a very good tutorial. http://blogs.msdn.com/b/shawnhar/archive/2010/08/04/dualtextureeffect.aspx>
Am I the only one experiencing this? I have nothing but a little, tiny, game, but it's close to unplayable now because of FPS drops.
Here's my code, if anyone is wondering:
Game1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;
namespace Innovationally
{
enum GameState
{
TITLESCREEN,
HELPSCREEN,
PLAYING,
WON,
LOST
}
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
GameState gameState = GameState.PLAYING;
//PLAYER STATS
public static Player player;
KeyboardState currentKeyboardState;
KeyboardState previousKeyboardState;
float playerMoveSpeed;
//COLLISION STATS
Rectangle kollision;
int bHit;
//LEVEL STATS
int level_number = 0;
int loadlevel = 0;
Texture2D hud, level0, level1, level2, level3, level4, level5;
Vector2 levelPos;
//ROOM STATS
List<int> tile_life = new List<int>();
Texture2D tile_gfx, stairsUp, stairsDown;
List<Vector2> tile_position = new List<Vector2>();
List<int> tile_type = new List<int>();
List<int> tile_elev = new List<int>();
int antlabb = 0;
int antvapen = 0;
int antpolis = 0;
int antwavers = 0;
int researchSpan;
//MISC
SpriteFont font;
Loot loot;
//GAMEPLAY STATS
TimeSpan timeElapsed;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 800;
graphics.PreferredBackBufferWidth = 900;
}
protected override void Initialize()
{
player = new Player();
playerMoveSpeed = 4.0f;
levelPos.X = 0;
levelPos.Y = 0;
loot = new Loot();
researchSpan = 120;
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Vector2 playerPosition = new Vector2(430, 450);
//LEVEL STATS
LaddaLevel(level_number);
level0 = Content.Load<Texture2D>("level0");
level1 = Content.Load<Texture2D>("level1");
level2 = Content.Load<Texture2D>("level2");
level3 = Content.Load<Texture2D>("level3");
level4 = Content.Load<Texture2D>("level4");
level5 = Content.Load<Texture2D>("level5");
hud = Content.Load<Texture2D>("hud");
//ROOM STATS
tile_gfx = Content.Load<Texture2D>("tile");
stairsUp = Content.Load<Texture2D>("stairsUp");
stairsDown = Content.Load<Texture2D>("stairsDown");
font = Content.Load<SpriteFont>("SpriteFont1");
player.Initialize(Content.Load<Texture2D>("Leftplayer"), playerPosition);
//SOMEONE STOP THE MUSIC, MUSIC.
MediaPlayer.Volume = 0.5f;
MediaPlayer.IsRepeating = true;
MediaPlayer.Play(Content.Load<Song>("barn-beat"));
}
public void LaddaLevel(int nummer)
{
StreamReader SR = new StreamReader(nummer.ToString());
string bana = SR.ReadToEnd();
SR.Close();
int temp_positionY = 0;
int temp_positionX = 0;
tile_position.Clear();
tile_type.Clear();
tile_life.Clear();
for (int i = 0; i < bana.Length; i++)
{
switch (bana[i])
{
case ' ':
temp_positionX++;
break;
case '0':
tile_life.Add(loot.myRnd.Next(8));
tile_position.Add(new Vector2((temp_positionX * 100), (temp_positionY * 100)));
temp_positionX++;
tile_type.Add(int.Parse(bana[i].ToString()));
break;
case '8':
tile_position.Add(new Vector2((temp_positionX * 100), (temp_positionY * 100)));
temp_positionX++;
tile_type.Add(int.Parse(bana[i].ToString()));
tile_life.Add(8);
break;
case '9':
tile_position.Add(new Vector2((temp_positionX * 100), (temp_positionY * 100)));
temp_positionX++;
tile_type.Add(int.Parse(bana[i].ToString()));
tile_life.Add(9);
break;
case '\n':
temp_positionY++;
temp_positionX = 0;
break;
}
}
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
previousKeyboardState = currentKeyboardState;
currentKeyboardState = Keyboard.GetState();
if (currentKeyboardState.IsKeyDown(Keys.Escape) && previousKeyboardState.IsKeyUp(Keys.Escape))
this.Exit();
switch (gameState)
{
case GameState.TITLESCREEN:
if (currentKeyboardState.IsKeyDown(Keys.S) && previousKeyboardState.IsKeyUp(Keys.S))
gameState = GameState.PLAYING;
if (currentKeyboardState.IsKeyDown(Keys.H) && previousKeyboardState.IsKeyUp(Keys.H))
gameState = GameState.HELPSCREEN;
break;
case GameState.HELPSCREEN:
if (currentKeyboardState.IsKeyDown(Keys.B) && previousKeyboardState.IsKeyUp(Keys.B))
gameState = GameState.TITLESCREEN;
break;
case GameState.PLAYING:
timeElapsed += gameTime.ElapsedGameTime;
UpdatePlayer(gameTime);
UpdateResearchCenters(gameTime);
UpdateCollisions(gameTime);
break;
case GameState.LOST:
if (currentKeyboardState.IsKeyDown(Keys.S) && previousKeyboardState.IsKeyUp(Keys.S))
{
loadlevel = 0;
gameState = GameState.PLAYING;
}
break;
}
base.Update(gameTime);
}
private void UpdatePlayer(GameTime gameTime)
{
if (currentKeyboardState.IsKeyDown(Keys.Left))
{
player.angle = (float)Math.PI * 1.5f;
player.Position.X -= playerMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Right))
{
player.angle = (float)Math.PI / 2;
player.Position.X += playerMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Up))
{
player.angle = (float)Math.PI * 2;
player.Position.Y -= playerMoveSpeed;
}
if (currentKeyboardState.IsKeyDown(Keys.Down))
{
player.angle = (float)Math.PI;
player.Position.Y += playerMoveSpeed;
}
if (player.health <= 0)
gameState = GameState.LOST;
}
public void UpdateResearchCenters(GameTime gameTime)
{
researchSpan -= gameTime.ElapsedGameTime.Seconds;
if (researchSpan <= 0)
{
loot.RandomResearch();
researchSpan = 120;
}
}
public void UpdateCollisions(GameTime gameTime)
{
Rectangle playerBox = new Rectangle((int)player.Position.X - 20, (int)player.Position.Y - 20, 40, 37);
Rectangle levelBox = new Rectangle(0, 0, 900, 800);
for (int i = 0; i < tile_position.Count; i++)
{
Rectangle tileBox = new Rectangle((int)tile_position[i].X, (int)tile_position[i].Y, 100, 100);
if (playerBox.Intersects(tileBox))
{
if (tile_life[i] <= 9)
{
if (tile_life[i] == 9 && currentKeyboardState.IsKeyDown(Keys.Space))
{
loadlevel += 1;
LaddaLevel(loadlevel);
}
else if (tile_life[i] == 8 && currentKeyboardState.IsKeyDown(Keys.Space))
{
loadlevel -= 1;
LaddaLevel(loadlevel);
}
else if (tile_life[i] == 7 && currentKeyboardState.IsKeyDown(Keys.Space))
{
loot.RandomLoot();
tile_life[i] = 70;
}
else if ((tile_life[i] == 6 || tile_life[i] == 60) && currentKeyboardState.IsKeyDown(Keys.Space) && (player.mvgelever >= 1 || player.problemelever >= 1 || player.normalaelever >= 1))
{
if (player.mvgelever >= 1)
{
player.mvgelever -= 1;
tile_elev.Add(1);
}
else if (player.normalaelever >= 1)
{
player.normalaelever -= 1;
tile_elev.Add(2);
}
else if (player.problemelever >= 1)
{
player.problemelever -= 1;
tile_elev.Add(3);
}
tile_life[i] = 60;
antlabb += 1;
}
if (tile_life[i] == 60 && currentKeyboardState.IsKeyDown(Keys.Space))
{
antlabb -= 1;
if (tile_elev.Contains(1))
player.mvgelever += 1;
if (tile_elev.Contains(2))
player.normalaelever += 1;
if (tile_elev.Contains(3))
player.problemelever += 1;
tile_life[i] = 6;
}
}
}
}
//Överlappar vi?
kollision = Intersection(playerBox, levelBox);
if (kollision.Width > 0 && kollision.Height > 0)
{
Rectangle r1 = Normalize(playerBox, kollision);
Rectangle r2 = Normalize(levelBox, kollision);
if (loadlevel == 0)
bHit = TestCollision(player.PlayerTexture, r1, level0, r2);
if (loadlevel == 1)
bHit = TestCollision(player.PlayerTexture, r1, level1, r2);
if (loadlevel == 2)
bHit = TestCollision(player.PlayerTexture, r1, level2, r2);
if (loadlevel == 3)
bHit = TestCollision(player.PlayerTexture, r1, level3, r2);
if (loadlevel == 4)
bHit = TestCollision(player.PlayerTexture, r1, level4, r2);
if (loadlevel == 5)
bHit = TestCollision(player.PlayerTexture, r1, level5, r2);
}
else
{
bHit = 0;
}
if (bHit == 1 || bHit == 2)
{
if (player.angle == (float)Math.PI)
player.Position.Y -= playerMoveSpeed;
if (player.angle == (float)Math.PI * 2)
player.Position.Y += playerMoveSpeed;
if (player.angle == (float)Math.PI / 2)
player.Position.X -= playerMoveSpeed;
if (player.angle == (float)Math.PI * 1.5f)
player.Position.X += playerMoveSpeed;
}
}
public static Rectangle Intersection(Rectangle r1, Rectangle r2)
{
int x1 = Math.Max(r1.Left, r2.Left);
int y1 = Math.Max(r1.Top, r2.Top);
int x2 = Math.Min(r1.Right, r2.Right);
int y2 = Math.Min(r1.Bottom, r2.Bottom);
if ((x2 >= x1) && (y2 >= y1))
{
return new Rectangle(x1, y1, x2 - x1, y2 - y1);
}
return Rectangle.Empty;
}
public static Rectangle Normalize(Rectangle reference, Rectangle overlap)
{
//Räkna ut en rektangel som kan användas relativt till referensrektangeln
return new Rectangle(
overlap.X - reference.X,
overlap.Y - reference.Y,
overlap.Width,
overlap.Height);
}
public static int TestCollision(Texture2D t1, Rectangle r1, Texture2D t2, Rectangle r2)
{
//Beräkna hur många pixlar som finns i området som ska undersökas
int pixelCount = r1.Width * r1.Height;
uint[] texture1Pixels = new uint[pixelCount];
uint[] texture2Pixels = new uint[pixelCount];
//Kopiera ut pixlarna från båda områdena
t1.GetData(0, r1, texture1Pixels, 0, pixelCount);
t2.GetData(0, r2, texture2Pixels, 0, pixelCount);
//Jämför om vi har några pixlar som överlappar varandra i områdena
for (int i = 0; i < pixelCount; ++i)
{
if (((texture1Pixels[i] & 0xff000000) > 0) && (texture2Pixels[i] == 0xffC3C3C3))
{
return 1;
}
if (((texture1Pixels[i] & 0xff000000) > 0) && (texture2Pixels[i] == 0xff000000))
{
return 2;
}
if (((texture1Pixels[i] & 0xff000000) > 0) && (texture2Pixels[i] == 0xff000000))
{
return 1;
}
}
return 0;
}
private void DrawHud()
{
string timeString = "TIME: " + timeElapsed.Minutes.ToString("00") + ":" + timeElapsed.Seconds.ToString("00");
spriteBatch.Draw(hud, new Vector2(0, 0), Color.White);
spriteBatch.DrawString(font, timeString, new Vector2(15, 35), Color.White);
spriteBatch.DrawString(font, "Level " + (loadlevel + 1), new Vector2(15, 10), Color.White);
spriteBatch.DrawString(font, "" + player.mvgelever, new Vector2(739, 55), Color.White);
spriteBatch.DrawString(font, "" + player.problemelever, new Vector2(799, 55), Color.White);
spriteBatch.DrawString(font, "" + player.normalaelever, new Vector2(859, 55), Color.White);
spriteBatch.DrawString(font, "" + antwavers, new Vector2(454, 55), Color.White);
spriteBatch.DrawString(font, "" + antpolis, new Vector2(514, 55), Color.White);
spriteBatch.DrawString(font, "" + antvapen, new Vector2(574, 55), Color.White);
spriteBatch.DrawString(font, "" + antlabb, new Vector2(633, 55), Color.White);
spriteBatch.DrawString(font, "" + player.coins, new Vector2(359, 55), Color.White);
spriteBatch.DrawString(font, "" + player.nyckel, new Vector2(328, 55), Color.White);
spriteBatch.DrawString(font, "" + player.bombs, new Vector2(296, 55), Color.White);
spriteBatch.DrawString(font, "RESEARCH IN: " + researchSpan, new Vector2(15, 55), Color.White);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
switch (gameState)
{
case GameState.TITLESCREEN:
break;
case GameState.PLAYING:
if (loadlevel == 0)
spriteBatch.Draw(level0, new Vector2(0, 0), Color.White);
if (loadlevel == 1)
spriteBatch.Draw(level1, new Vector2(0, 0), Color.White);
if (loadlevel == 2)
spriteBatch.Draw(level2, new Vector2(0, 0), Color.White);
if (loadlevel == 3)
spriteBatch.Draw(level3, new Vector2(0, 0), Color.White);
if (loadlevel == 4)
spriteBatch.Draw(level4, new Vector2(0, 0), Color.White);
if (loadlevel == 5)
spriteBatch.Draw(level5, new Vector2(0, 0), Color.White);
for (int i = 0; i < tile_position.Count; i++)
{
switch (tile_life[i])
{
case 0: spriteBatch.Draw(tile_gfx, tile_position[i], Color.White);
break;
case 1: spriteBatch.Draw(tile_gfx, tile_position[i], Color.HotPink);
break;
case 2: spriteBatch.Draw(tile_gfx, tile_position[i], Color.YellowGreen);
break;
case 3: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Purple);
break;
case 4: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Yellow);
break;
case 5: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Silver);
break;
case 6: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Gold);
break;
case 60: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Gold);
spriteBatch.Draw(player.PlayerTexture, new Vector2(tile_position[i].X + 40, tile_position[i].Y + 40), Color.White);
break;
case 7: spriteBatch.Draw(tile_gfx, tile_position[i], Color.Orange);
break;
case 70: spriteBatch.Draw(tile_gfx, tile_position[i], Color.DarkOrange);
break;
case 8: spriteBatch.Draw(stairsDown, tile_position[i], Color.White);
break;
case 9: spriteBatch.Draw(stairsUp, tile_position[i], Color.White);
break;
}
}
DrawHud();
player.Draw(spriteBatch);
break;
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Player class (Player.cs):
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Innovationally
{
public class Player
{
public Texture2D PlayerTexture;
public Vector2 Position;
public bool Active;
public float angle;
public int coins { get; set; }
public int bombs { get; set; }
public int normalaelever { get; set; }
public int health { get; set; }
public int damage { get; set; }
public int maximumhealth { get; set; }
public int problemelever { get; set; }
public int mvgelever { get; set; }
public int elever { get; set; }
public int nyckel { get; set; }
public int Width
{
get { return PlayerTexture.Width; }
}
public int Height
{
get { return PlayerTexture.Height; }
}
public void Initialize(Texture2D texture, Vector2 position)
{
PlayerTexture = texture;
Position = position;
Active = true;
elever = 0;
mvgelever = 0;
normalaelever = 0;
coins = 0;
bombs = 0;
health = 100;
maximumhealth = 100;
damage = 20;
nyckel = 1;
angle = (float)Math.PI * 2;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(PlayerTexture, Position, null, Color.White, angle, new Vector2(PlayerTexture.Width / 2, PlayerTexture.Height / 2), 1f, SpriteEffects.None, 0f);
}
}
}
And finally, Loot.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Innovationally
{
class Loot
{
Player player = Game1.player;
public Random myRnd = new Random();
public int primarylootnumber;
public int secondarylootnumber;
public int tertiarylootnumber;
public void RandomLoot()
{
primarylootnumber = myRnd.Next(1, 11);
switch (primarylootnumber)
{
case 1:player.coins++;
break;
case 2:player.coins += 3;
break;
case 3:player.coins += 5;
break;
case 4:player.normalaelever += 1;
break;
case 5:player.normalaelever += 2;
break;
case 6:player.health += 10;
break;
case 7:player.health += 30;
break;
case 8:player.health += 50;
break;
case 9:player.damage += 5;
break;
case 10:player.damage += 10;
break;
}
secondarylootnumber = myRnd.Next(1, 11);
switch (primarylootnumber)
{
case 1:player.maximumhealth += 10;
break;
case 2:player.coins += 10;
break;
case 3:player.damage += 15;
break;
case 4:player.mvgelever += 1;
break;
case 5:player.problemelever += 1;
break;
}
tertiarylootnumber = myRnd.Next(1, 31);
switch (primarylootnumber)
{
case 10:
player.mvgelever += 1;
player.problemelever += 1;
break;
case 20:player.coins += 50;
break;
case 30:player.maximumhealth += 30;
break;
}
}
public void RandomResearch()
{
primarylootnumber = myRnd.Next(1, 6);
switch (primarylootnumber)
{
case 1:player.maximumhealth += 30;
break;
case 2: player.damage += 20;
break;
case 3:
break;
case 4:
break;
case 5:
break;
}
}
}
}
The only red flag I can see at the moment is:
t1.GetData(0, r1, texture1Pixels, 0, pixelCount);
t2.GetData(0, r2, texture2Pixels, 0, pixelCount);
These calls have a high overhead. I would recommend, if you are doing per-pixel collision detection, caching or pre-computing the pixel data rather than retrieving the data from the texture every frame.
EDIT:
here is a toy implementation (NOT TESTED!) of how you may want to retrieve the pixel data. Hopefully this will be enough to get you started.
Here are two mini functions for getting the texture data. When initializing your game, use 'PixelMaps' passing in all of your textures (e.g in an array). You will then have a dictionary you can use to perform lookups of the pixel data. You will want to use the information gleamed from the Texture and the rectangle you are testing to pick the right pixels.
public static uint[] Pixels(Texture2D texture)
{
uint[] data = new uint[texture.Width * texture.Height];
texture.GetData(data);
return data;
}
public static Dictionary<Texture2D, uint[]> PixelMaps(IEnumerable<Texture2D> textures)
{
return textures.ToDictionary(t => t, Pixels);
}
The TestCollision function may now look something like this (I have tried to keep the code as close as possible to the original).
public static int TestCollision(uint[] t1,
int t1Width,
Rectangle r,
uint[] t2)
{
for(var x = r.X; x < r.X + r.Width; x++)
for (var y = r.Y; y < r.Y + r.Height; y++)
{
var i = x + (y * t1Width);
if (((t1[i] & 0xff000000) > 0) && (t2[i] == 0xffC3C3C3))
{
return 1;
}
if (((t1[i] & 0xff000000) > 0) && (t2[i] == 0xff000000))
{
return 2;
}
if (((t1[i] & 0xff000000) > 0) && (t2[i] == 0xff000000))
{
return 1;
}
}
return 0;
}
Hopefully that is enough to get you started! Have fun :)
EDIT2:
Ok more information, again, trying to not change your code too much here we go:
introduce a new private member for the pixel maps. e.g:
Dictionary<Texture2D, uint[]> pixelMaps;
In your init function try this (btw I would also put the levels in a dictionary using an enum as a key, look it up. You should never have fields/properties like 0,1,2,3 that just screams I need some kind of list/array/assoc data structure.):
//LEVEL STATS
level0 = Content.Load<Texture2D>("level0");
level1 = Content.Load<Texture2D>("level1");
level2 = Content.Load<Texture2D>("level2");
level3 = Content.Load<Texture2D>("level3");
level4 = Content.Load<Texture2D>("level4");
level5 = Content.Load<Texture2D>("level5");
//As you can see I'm using the new PixelMaps function here...
pixelMaps = PixelMaps(new[] { level0, level1, level2, level3, level4, level5 });
When you come to test collisions you can do this:
var playerMap = pixelMaps[player.PlayerTexture];
var level0Map = pixelMaps[level0];
if (loadlevel == 0)
bHit = TestCollision(playerMap, r1, level0Map);
The best and quickest way to solve this problem (and many others while your at it) is to use a profiler. It will be able to show you what methods (and possibly lines, ANTS supports this) are taking the longest to complete. Once you narrow it down you can figure out how to fix these individual problems.
As for the code you posted, I'd have to agree with thedajaw that the collision code has alot of room for optimization. Getting the texture data everyframe is never a good idea, and should be done once at the begining of the game and stored in a variable for later use.
Overall I think the rest is fine, but see what the profiler shows up. Some minor structure issues (Could use some else ifs instead of ifs, things could be handled better,etc)
I'd recommend to read this question I asked a while back on a simlar subject.
The original code is:
partial class Game1 : Microsoft.Xna.Framework.Game
{
public enum GameState
{
StateMainMenu,
StatePlaying,
StateGameOver,
StateHelp,
}
GameState currentState = GameState.StateMainMenu;
KeyboardState kbState;
Keys[] pressedKeys;
Queue<FallingCharacter> Letters = new Queue<FallingCharacter>();
float nextLetterTime = 0.6f;
int NextSpeedup = 20; // in 20 points lets speed it up
int iSpeed = 2;
int Score = 0;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont spriteFont;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.ApplyChanges();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spriteFont = Content.Load<SpriteFont>("GameFont");
base.LoadContent();
}
public void OnKeyPressed(Keys k)
{
if ((currentState == GameState.StateMainMenu ||
currentState == GameState.StateGameOver)
&& k == Keys.Enter)
{
currentState = GameState.StatePlaying;
nextLetterTime = 0.0f;
NextSpeedup = 20; // in 20 points lsets speed it up
iSpeed = 1;
Score = 0;
}
else if (currentState == GameState.StatePlaying)
{
string sName = Enum.GetName(typeof(Keys), k);
if (Letters.Count > 0 &&
String.Compare(Letters.Peek().character.ToString(), sName) == 0)
{
Score += 100;
Letters.Dequeue();
NextSpeedup--;
if (NextSpeedup <= 0)
{
iSpeed++;
NextSpeedup = 20;
}
}
}
if (k == Keys.Escape)
{
this.Exit();
}
}
protected override void Update(GameTime gameTime)
{
// The time since Update was called last
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
kbState = Keyboard.GetState();
Keys[] newKeys = (Keys[])kbState.GetPressedKeys().Clone();
if (pressedKeys != null)
{
foreach (Keys k in newKeys)
{
bool bFound = false;
foreach (Keys k2 in pressedKeys)
{
if (k == k2)
{
bFound = true;
break;
}
}
if (!bFound)
{
OnKeyPressed(k);
}
}
}
pressedKeys = newKeys;
if (currentState == GameState.StatePlaying)
{
foreach (FallingCharacter fc in Letters)
{
if (fc.Pos.Y + 50 > graphics.PreferredBackBufferHeight)
{
currentState = GameState.StateGameOver;
Letters.Clear();
break;
}
else
{
fc.Pos.Y += (elapsed * (float)(iSpeed * 40));
}
}
nextLetterTime -= elapsed;
if (nextLetterTime <= 0 && currentState != GameState.StateGameOver)
{
nextLetterTime = 0.75f - (iSpeed * .03f);
Random r = new Random();
Letters.Enqueue(new FallingCharacter(
r.Next(graphics.PreferredBackBufferWidth - 30), -30,
Color.LightGreen, (char)((int)'A' + r.Next(25))));
}
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
switch (currentState)
{
case GameState.StateMainMenu:
{
spriteBatch.DrawString(spriteFont,
"Press Enter to begin",
new Vector2(graphics.PreferredBackBufferWidth / 4,
graphics.PreferredBackBufferHeight / 2),
Color.White);
}
break;
case GameState.StatePlaying:
{
spriteBatch.DrawString(spriteFont,
"Score: " + Score.ToString(),
new Vector2(10, 10), Color.White);
foreach (FallingCharacter fc in Letters)
{
fc.Render(spriteBatch, spriteFont);
}
}
break;
case GameState.StateGameOver:
{
spriteBatch.DrawString(spriteFont,
"Score: " + Score.ToString(),
new Vector2(10, 10), Color.White);
spriteBatch.DrawString(spriteFont,
"Game Over",
new Vector2(graphics.PreferredBackBufferWidth / 3,
graphics.PreferredBackBufferHeight / 2),
Color.LightBlue);
spriteBatch.DrawString(spriteFont,
"Press Return to Continue",
new Vector2(graphics.PreferredBackBufferWidth / 6,
graphics.PreferredBackBufferHeight / 2 + 50),
Color.LightBlue);
}
break;
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
and I need change the quque to list().
after I changed Queue Letters = new Queue();
to List Letters = new List();
Can anyone help me what need change next.
I feel really confused about this, thank you very much.
If you want to keep the same behavior of the Queue (First-In-First-Out), you must do the following changes(changes in bold):
if (Letters.Count > 0 &&
String.Compare(Letters.Peek().character.ToString(),
sName) == 0)
changes to
if (Letters.Count > 0 &&
String.Compare(Letters.First().character.ToString(),
sName) == 0)
to keep the behavior where Peek returns the first character.
Letters.Dequeue();
changes to
Letters.RemoveAt(0);
to remove the first element like Dequeue does.
Note that you could do a check to make sure that the List is not empty.
Letters.Enqueue(new FallingCharacter(
r.Next(graphics.PreferredBackBufferWidth
- 30), -30,
Color.LightGreen, (char)((int)'A' + r.Next(25))));
changes to
Letters.Add(new FallingCharacter(
r.Next(graphics.PreferredBackBufferWidth
- 30), -30,
Color.LightGreen, (char)((int)'A' + r.Next(25))));
to append the FallingCharacter to the end of the list.