Well i made a bunny that teleports on tap and i want to make it so if you hold for more than 0.3f a bubble activates and protects it i tried multiple code variates but i cant get it to work in some situation the bunny teleports and activates the bubble after and in others it doesnt i know its something simple and i just have to adjust the if / else if so i will be thankfull for eny help
using UnityEngine;
using System.Collections;
public class tap : MonoBehaviour {
// Use this for initialization
public GameObject Bunny;
public GameObject BunnyUpEffect;
public GameObject BunnyDownEffect;
public static bool IsHeld = false;
float TimeHeld = 0f;
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButton (0)) {
TimeHeld += Time.deltaTime;
if (TimeHeld > 0.3f) {
BubbleScript.BubbleActive = true;
IsHeld = true;
}
}
else {
BubbleScript.BubbleActive = false;
IsHeld = false;
TimeHeld = 0f;
if (Input.GetMouseButtonDown(0) && IsHeld == false) {
if (BunnyScript.BunnyAlive == true) {
if (BunnyScript.RunBottom == true) {
if (Stats.Energy > 0) {
BunnyUpEffect.GetComponent<BunnyUpEffect> ().Up ();
}
} else if (BunnyScript.RunBottom == false) {
BunnyDownEffect.GetComponent<BunnyDownEffect> ().Down ();
}
Bunny.GetComponent<BunnyScript> ().ChangePos ();
}
}
}
}
}
Related
I'm trying to write the Space Invaders clone for Windows console, and it felt like everything was going fine, but here comes this crash. The program compiles without errors, however instantly crashes on start up.
I admit that I don't know pointers very well, and I believe that the problem is somewhere there.
#include "stdafx.h"
#include <vector>
#include <random>
#include <chrono>
#include <thread>
#include <memory>
#include <SDKDDKVer.h>
#include "Vector2D.h"
#include "Renderer.h"
std::default_random_engine rGen;
typedef std::uniform_int_distribution<int> intRand;
typedef std::uniform_real_distribution<float> floatRand;
char ObjectType[][64] =
{
"ot_AlienShip",
"ot_PlayerShip",
"ot_AlienLaser",
"ot_PlayerLaser",
"ot_Explosion"
};
class PlayField;
class GameObject
{
public:
char* m_objType = nullptr;
Vector2D pos;
unsigned char sprite;
virtual void Update(PlayField& world) {};
virtual bool DecreaseHealth() { return true; };
};
class Input
{
public:
virtual bool Left() = 0;
virtual bool Right() = 0;
virtual bool Fire() = 0;
};
class RndInput : public Input
{
public:
virtual bool Left() override { floatRand keyRate(0, 1); return (keyRate(rGen) < 0.3f); }
virtual bool Right() override { floatRand keyRate(0, 1); return (keyRate(rGen) < 0.4f); };
virtual bool Fire() override { floatRand keyRate(0, 1); return (keyRate(rGen) < 0.5f); };
};
class PlayField
{
private:
typedef GameObject* GameObjPtr;
std::vector<GameObjPtr> gameObjects;
public:
Input* cotrollerInput = nullptr;
GameObject* it = new GameObject;
//it = new GameObject;
Vector2D bounds;
// Number of available active laser slots for aliens and player
int AlienLasers = 10;
int PlayerLasers = 4;
explicit PlayField(Vector2D iBounds) : bounds(iBounds) {};
const std::vector<GameObjPtr>& GameObjects() { return gameObjects; }
void Update()
{
// update list of active objects in the world
for (auto it : gameObjects)
{
it->Update(*this); //The crash is here "Unhandled exception thrown: read access violation. it was 0xFFFFFFFFFFFFFFFF."
}
}
GameObject* GetPlayerObject()
{
auto it = std::find_if(gameObjects.begin(), gameObjects.end(), [](GameObjPtr in) { return (strcmp(in->m_objType,"ot_PlayerShip")==0); });
if (it != gameObjects.end())
return (*it);
else
return nullptr;
}
void SpawnLaser(GameObject* newObj)
{
if (strcmp(newObj->m_objType, "ot_AlienLaser")==0)
AlienLasers--;
else if (strcmp(newObj->m_objType, "ot_PlayerLaser")==0)
PlayerLasers--;
AddObject(newObj);
}
void DespawnLaser(GameObject* newObj)
{
if (strcmp(newObj->m_objType, "ot_AlienLaser")==0)
AlienLasers++;
else if (strcmp(newObj->m_objType, "ot_PlayerLaser")==0)
PlayerLasers++;
RemoveObject(newObj);
}
void AddObject(GameObject* newObj)
{
//gameObjectsToAdd.push_back(GameObjPtr(newObj));
gameObjects.push_back(newObj);
}
void RemoveObject(GameObject* newObj)
{
//gameObjectsToRemove.push_back(newObj);
auto it = std::find_if(gameObjects.begin(), gameObjects.end(), [&](GameObjPtr in) { return (in==newObj); });
gameObjects.erase(it);
}
};
class Explosion : public GameObject
{
public:
// Explosion lasts 5 ticks before it dissappears
int timer = 5;
Explosion() { m_objType = new char[64]; strcpy(m_objType, "ot_Explosion"); sprite = RS_Explosion; }
~Explosion() { delete[] m_objType; }
void Update(PlayField& world) override
{
timer--;
if (!timer)
{
world.RemoveObject(this);
delete this;
}
}
};
class AlienLaser : public GameObject
{
public:
AlienLaser() { m_objType = new char[64]; strcpy(m_objType, "ot_AlienLaser"); sprite = RS_AlienLaser; }
~AlienLaser() { delete[] m_objType; }
void Update(PlayField& world) override
{
bool deleted = false;
pos.y += 1.f;
if (pos.y > world.bounds.y)
{
deleted = true;
}
GameObject* player = world.GetPlayerObject();
if (player && pos.IntCmp(player->pos))
{
deleted = true;
//Spawn explosion, kill player
GameObject& no = *(new Explosion);
no.pos = pos;
world.AddObject(&no);
world.RemoveObject(player);
}
if (deleted)
{
world.DespawnLaser((GameObject*)this);
delete this;
}
}
};
class PlayerLaser : public GameObject
{
public:
PlayerLaser() { m_objType = new char[64]; strcpy(m_objType, "ot_PlayerLaser"); sprite = RS_PlayerLaser; }
~PlayerLaser() { delete[] m_objType; }
void Update(PlayField& world) override
{
bool deleted = false;
pos.y -= 1.f;
if (pos.y < 0)
{
deleted = true;
}
for (auto it : world.GameObjects())
{
if (strcmp(it->m_objType,"ot_AlienShip")==0 && it->pos.IntCmp(pos))
{
deleted = true;
//Spawn explosion, kill the alien that we hit
GameObject& no = *(new Explosion);
no.pos = pos;
world.AddObject(&no);
if (it->DecreaseHealth())
world.RemoveObject(it);
}
}
if (deleted)
{
world.DespawnLaser(this);
delete this;
}
}
};
class Alien : public GameObject
{
public:
Alien() { m_objType = new char[64]; strcpy(m_objType, "ot_AlienShip"); sprite = RS_Alien; }
~Alien() { delete m_objType; }
private:
const float maxUpdateRate = 0.01f;
const float transformEnergy = 1.f;
enum AlienState
{
as_Normal,
as_Better
};
// Variables dictating energy level for upgrade, direction of movement, and current speed
float health = 1.f;
float energy = 0.f;
float direction = 1.f;
float velocity = 0.5f;
AlienState state{};
void Transform()
{
state = as_Better;
sprite = RS_BetterAlien;
velocity *= 2.f;
}
bool DecreaseHealth() override { health -= 1.f; return health <= 0; }
void Update(PlayField& world) override
{
pos.x += direction * velocity;
// Border check
if (pos.x < 0 || pos.x >= world.bounds.x - 1)
{
direction = -direction;
pos.y += 1;
}
// Border check vertical:
if (pos.y >= world.bounds.y - 1)
{
// kill player
GameObject* player = world.GetPlayerObject();
if (player && pos.IntCmp(player->pos))
{
//Spawn explosion
GameObject& no = *(new Explosion);
no.pos = pos;
world.AddObject(&no);
world.RemoveObject(player);
}
}
// Transform into better Alien
if (state!=as_Better)
{
floatRand updateRate(-maxUpdateRate, 2*maxUpdateRate);
energy += updateRate(rGen);
if (energy >= transformEnergy)
Transform();
}
floatRand fireRate(0, 1);
if (fireRate(rGen) < 0.5 && world.AlienLasers>0)
{
//Spawn laser
GameObject& newLaser = *(new AlienLaser);
newLaser.pos = pos;
world.SpawnLaser(&newLaser);
}
}
};
class PlayerShip : public GameObject
{
public:
PlayerShip() { m_objType = new char[64]; strcpy(m_objType, "ot_PlayerShip"); sprite = RS_Player; }
~PlayerShip() { delete m_objType; }
void Update(PlayField& world) override
{
if (world.cotrollerInput->Left())
pos.x -= 1;
else if (world.cotrollerInput->Right())
pos.x += 1;
if (world.cotrollerInput->Fire() && world.PlayerLasers>0)
{
//Spawn laser
GameObject& newLaser = *(new PlayerLaser);
newLaser.pos = pos;
world.SpawnLaser(&newLaser);
}
}
};
int main()
{
rGen.seed(1);
Vector2D size(80, 28);
Renderer mainRenderer(size);
PlayField world(size);
intRand xCoord(0, (int)size.x-1);
intRand yCoord(0, 10);
// Populate aliens
for (int k = 0; k < 20; k++)
{
Alien& a = *(new Alien);
a.pos.x = (float)xCoord(rGen);
a.pos.y = (float)yCoord(rGen);
world.AddObject(&a);
}
// Add player
PlayerShip& p = *(new PlayerShip);
p.pos = Vector2D(40, 27);
world.AddObject(&p);
world.Update();
{
RenderItemList rl;
for (auto it : world.GameObjects())
{
RenderItem a = RenderItem(Vector2D(it->pos), it->sprite);
rl.push_back(a);
}
mainRenderer.Update(rl);
// Sleep a bit so updates don't run too fast
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
return 0;
}
In addition, VS gives the following info:
I assume, that the pointer (or the object) appears to be cleared somewhere before, but I have no idea how to trace it. Thanks in advance.
The various ::Update methods you have add and remove objects from gameObjects while you are traversing it in Playfield::Update. This is a guaranteed crash as it invalidates the implicit iterator in your for loop.
To solve this, either:
Have GameObject::Update return a boolean that signifies if the object can be removed or not. This requires you to rewrite the loop in Playfield::Update with explicit iterators so you an do it = gameObjects.erase(it);. This will still not allow you to add new objects, though.
Defer additions and removals until the end of the game loop. Add a markForAddition / markForRemoval method that will remove these objects from the game world after Playfield::Update has gone through. You will need to do some extra bookkeeping to make sure you do not update or draw objects that have been removed earlier in the same loop, but that is surmountable.
Switch data structures: a std::list does not invalidate its iterators if you remove an object somewhere. You do still need to be careful with the current element though.
I have create a walkthrough android studio screen of 3 slides and I need that when I push the button mNextBtn, at the third slide, it change to another Java class. As you can see in the code below I've used an if statement but it doesn't work because when I run and I push the mButtonBtn button the app stop, how can I fix it?
public class Portada extends AppCompatActivity {
private ViewPager mSlideViewPager;
private LinearLayout mDotLayout;
private TextView[] mDots;
private SliderAdapter sliderAdapter;
private Button mNextBtn;
private Button mBackBtn;
private int mCurrentpage;
int mLogin;
public void onLogin (){
if (mDots.length == 3){
Intent intent= new Intent(Portada.this, Login.class);
startActivity(intent);
}else
{
mSlideViewPager.setCurrentItem(mCurrentpage + 1);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_portada);
mSlideViewPager = (ViewPager) findViewById(R.id.slideViewPager);
mDotLayout = (LinearLayout) findViewById(R.id.dotsLayout);
mNextBtn = (Button) findViewById(R.id.nextBtn);
mBackBtn = (Button) findViewById(R.id.prevBtn);
sliderAdapter = new SliderAdapter(this);
mSlideViewPager.setAdapter(sliderAdapter);
addDotsIndicator(0);
mSlideViewPager.addOnPageChangeListener(viewListerer);
mNextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mDots.length == 3){
Intent intent= new Intent(getApplicationContext(), Login.class);
startActivity(intent);
}else
{
mSlideViewPager.setCurrentItem(mCurrentpage + 1);
}
}
});
mBackBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mSlideViewPager.setCurrentItem(mCurrentpage - 1);
}
});
}
public void addDotsIndicator(int position) {
mDots = new TextView[3];
mDotLayout.removeAllViews();
for(int i = 0; i < mDots.length; i++ ){
mDots[i] = new TextView(this);
mDots[i].setText(Html.fromHtml("•"));
mDots[i].setTextSize(50);
mDots[i].setTextColor(getResources().getColor(R.color.colorTransparentWhite));
mDotLayout.addView(mDots[i]);
}
if (mDots.length > 0){
mDots[position].setTextColor(getResources().getColor(R.color.colorWhite));
}
}
ViewPager.OnPageChangeListener viewListerer = new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
addDotsIndicator(i);
mCurrentpage = i;
if (i == 0){
mNextBtn.setEnabled(true);
mBackBtn.setEnabled(false);
mBackBtn.setVisibility(View.INVISIBLE);
mNextBtn.setText("NEXT");
mBackBtn.setText("");
}else if(i == mDots.length - 1) {
mNextBtn.setEnabled(true);
mBackBtn.setEnabled(true);
mBackBtn.setVisibility(View.VISIBLE);
mNextBtn.setText("FINISH");
mBackBtn.setText("BACK");
}else {
mNextBtn.setEnabled(true);
mBackBtn.setEnabled(true);
mBackBtn.setVisibility(View.VISIBLE);
mNextBtn.setText("NEXT");
mBackBtn.setText("BACK");
}
}
#Override
public void onPageScrollStateChanged(int i) {
}
};
}
`
I am a beginner in threading with C++. Tried to create a thread t1 inside the class, but I want it not to be initialized. For this I did:
In the class variable, thread *t1 as if were to declare the class variable without initializing it.
Then from the constructor, I did:
t1 = new Thread(functionName);
But, there's some error that I didn't get. I previously had simple working experience with threading in Java.
Will this strategy cause an interlocking problem, assuming the solution exists to the way I want to implement it. (if I want to access the same variable without modifying it). Code goes like this:
class game:protected gameObjects
{
thread *t1;
///-------------------- Variables-------------------///
char keyPressed = NULL;
/// structure for holding player information.
struct player
{
int x, y0, y1,color;
};
player player1, player2;
/// for ball
int ballX, ballY, ballColor, ballBorderColor;
///--------------------------------------------------///
void initializeData()
{
ballX = 42;
ballY = 130;
player1.color = LIGHTCYAN;
player1.x = 30;
player1.y0 = 100;
player1.y1 = 200;
player2.color = LIGHTMAGENTA;
player2.x = 600;
player2.y0 = 100;
player2.y1 = 200;
/// Basic setUp For Game and Game Screen
ballBorderColor = RED;
ballColor = GREEN;
}
void updateScoreBoard()
{
/// whole score board border.
drawRect(20,10,620,50,RED);
/// left score board
drawRect(21,11,321,49,CYAN);
setfillstyle(SOLID_FILL,CYAN);
floodfill(30,40,CYAN);
setbkcolor(CYAN);
setcolor(LIGHTGREEN);
outtextxy(35,20,"Score:0");
///right score board.
drawRect(323,11,619,49,LIGHTMAGENTA);
setfillstyle(SOLID_FILL,LIGHTMAGENTA);
floodfill(330,40,LIGHTMAGENTA);
setbkcolor(LIGHTMAGENTA);
setcolor(LIGHTGREEN);
outtextxy(350,20,"Score:1");
}
void ballPosition()
{
setfillstyle(SOLID_FILL,ballColor);
drawCircle(ballX,ballY,10,ballBorderColor); ///ball for game
floodfill(ballX,ballY,ballBorderColor);
}
void playerBatPosition()
{
drawLine(player1.x,player1.y0,player1.x,player1.y1,player1.color);
drawLine(player2.x,player2.y0,player2.x,player2.y1,player2.color);
}
void setBackground()
{
setfillstyle(SOLID_FILL,background);
drawRect(0,0,getmaxx(),getmaxy(),RED);
floodfill(getmaxx()/2,getmaxy()/2,RED);
drawRect(20,60,620,470,WHITE); ///white line.
}
void updateScreenActivity()
{
playerBatPosition();
}
void startPlaying()
{
do
{
keyPressed = _getch();
if(keyPressed == 'w')
{
if(player1.y0 > 60)
{
drawLine(player1.x,player1.y0,player1.x,player1.y1,background);
player1.y0-=5;
player1.y1-=5;
}
}
else if(keyPressed == 's')
{
if(player1.y1 < 470)
{
drawLine(player1.x,player1.y0,player1.x,player1.y1,background);
player1.y0+=5;
player1.y1+=5;
}
}
if(keyPressed == 't')
{
if(player2.y0 > 60)
{
drawLine(player2.x,player2.y0,player2.x,player2.y1,background);
player2.y0-=5;
player2.y1-=5;
}
}
else if(keyPressed == 'g')
{
if(player2.y1 < 470)
{
drawLine(player2.x,player2.y0,player2.x,player2.y1,background);
player2.y0+=5;
player2.y1+=5;
}
}
updateScreenActivity();
}
while(keyPressed != 'q');
}
///-------------------Threading call --------------///
void startBallMovement(){
cout<<"Hello world"<<endl;
}
///-----------------------------------------------///
public:
game()
{
cleardevice();
initializeData();
setBackground();
updateScoreBoard();
playerBatPosition();
ballPosition();
startPlaying();
t1 = new thread(startBallMovement);
}
};
What I want to do is create a movement of a circle in different paths from the thread. I might sometimes need to access the variables from the thread to simulate the movement in different directions as per the user's strategy.
Error:
Your class implementation looks a bit lousy. But try something like this.
class game
{
private: thread* t;
public:
game()
{
t = new thread([this]() {startBallMovement();} );
}
~game()
{
if(t != nullptr)
{
t->join();
delete t;
}
}
void startBallMovement()
{
}
};
I am trying to add a command-line interface to an existing MFC application, and found a class online at this website. I have adapted it to my needs and when I try to build I get an error that reads "error C2248: 'CCustomCommandLineInfo::CCustomCommandLineInfo' : cannot access private member declared in class 'CCustomCommandLineInfo'" here's my code:
class CCustomCommandLineInfo : public CCommandLineInfo
{
CCustomCommandLineInfo()
{
//m_bExport = m_bOpen = m_bWhatever = FALSE;
m_bNoGUI = m_baMode = FALSE;
}
// for convenience maintain 3 variables to indicate the param passed.
BOOL m_bNoGUI; //for /nogui (No GUI; Command-line)
BOOL m_baMode; //for /adv (Advanced Mode)
// BOOL m_bWhatever; //for /whatever (3rd switch - for later date)
//public methods for checking these.
public:
BOOL NoGUI() { return m_bNoGUI; };
BOOL aModeCmd() { return m_baMode; };
//BOOL IsWhatever() { return m_bWhatever; };
virtual void ParseParam(const char* pszParam, BOOL bFlag, BOOL bLast)
{
if(0 == strcmp(pszParam, "/nogui"))
{
m_bNoGUI = TRUE;
}
else if(0 == strcmp(pszParam, "/adv"))
{
m_baMode = TRUE;
}
// else if(0 == strcmp(pszParam, "/whatever"))
// {
// m_bWhatever = TRUE;
// }
}
};
And here's what I have in my InitInstance()
// parse command line (cmdline.h)
CCustomCommandLineInfo oInfo;
ParseCommandLine(oInfo);
if(oInfo.NoGUI())
{
// Do something
}
else if(oInfo.aModeCmd())
{
// Do whatever
}
How would I go about fixing this?
You have:
class CCustomCommandLineInfo : public CCommandLineInfo
{
CCustomCommandLineInfo()
{
//m_bExport = m_bOpen = m_bWhatever = FALSE;
m_bNoGUI = m_baMode = FALSE;
}
That makes the default constructor a private function. That's why you can't use:
CCustomCommandLineInfo oInfo;
Make the default constructor public.
class CCustomCommandLineInfo : public CCommandLineInfo
{
public:
CCustomCommandLineInfo()
{
//m_bExport = m_bOpen = m_bWhatever = FALSE;
m_bNoGUI = m_baMode = FALSE;
}
Why, although I have add 4 GameObjects, in the GameLoop the Console give only one times "GameObject Update" and "GameObject Render" out ?
And another Qustion, how I can made a Self Destroy Function for the GameObjects?
And the last Question, whats the best methode, that a GameObject can communicate with other game objects in the list?
#include <iostream>
using namespace std;
class GameObject
{
public:
GameObject *nextGameObject;
GameObject()
{
cout<<"GameObject Constructor!\n";
nextGameObject = nullptr;
}
~GameObject()
{
cout<<"GameObject Destructor\n";
if(nextGameObject != nullptr)
{
delete nextGameObject;
}
}
virtual void Update()
{
cout<<"GameObject Update!\n";
}
virtual void Render()
{
cout<<"GameObject Render!\n";
}
};
class GameObjectManager
{
private:
GameObject *firstGameObject;
public:
GameObjectManager()
{
firstGameObject = nullptr;
}
~GameObjectManager()
{
if(firstGameObject != nullptr)
{
delete firstGameObject;
}
}
void Update()
{
if(firstGameObject != nullptr)
{
GameObject *helpGameObject = firstGameObject;
while(helpGameObject != nullptr)
{
helpGameObject->Update();
helpGameObject = helpGameObject->nextGameObject;
}
}
}
void Render()
{
if(firstGameObject != nullptr)
{
GameObject *helpGameObject = firstGameObject;
while(helpGameObject != nullptr)
{
helpGameObject->Render();
helpGameObject = helpGameObject->nextGameObject;
}
}
}
void Add(GameObject *newGameObject)
{
if(firstGameObject == nullptr)
{
firstGameObject = newGameObject;
}
else
{
GameObject *helpGameObject = firstGameObject;
while(helpGameObject != nullptr)
{
helpGameObject = helpGameObject->nextGameObject;
}
helpGameObject = newGameObject;
}
}
};
int main()
{
GameObjectManager gom;
bool run = true;
gom.Add(new GameObject);
gom.Add(new GameObject);
gom.Add(new GameObject);
gom.Add(new GameObject);
while(run)
{
cout<<"GameLoop Start\n";
gom.Update();
gom.Render();
cout<<"GameLoop End\n";
cin.get();
}
return 0;
}
This is a horrible solution for a linked list, but I'll answer your question. The fault is in Add(). Here, you just modify the local variable helpGameObject. Instead you should stop at the object that has no successor and modify that objects nextGameObject.
The problem is in your Add function.
the follwing line:
helpGameObject = newGameObject;
doesn't actually change the value pointed to by helpGameObject, rather it changes the pointer itself.
I think the best solution is to change it to the following
GameObject *helpGameObject = firstGameObject;
while(helpGameObject->nextGameObject != nullptr)
{
helpGameObject = helpGameObject->nextGameObject;
}
helpGameObject->nextGameObject = newGameObject;