Recently I've noticed that AI products are emerging in new directions, especially with the innovative products launched by some of the tech giants. For example, today we're going to explore the Tencent Cloud-developedCloud Development CloudBaseIf you haven't heard the name before, you may remember another product launched by Tencent Cloud - thetweedCloudBase is the micro-build platform that incorporates AI capabilities. That's right, CloudBase is that micro-build platform that incorporates AI capabilities, which helps users build websites more efficiently and conveniently, especially for users who are unfamiliar with development, greatly reducing the technical threshold.
In the previous section, I gave a primer on the AI capabilities of cloud development, which mentioned the ability to generate a web page from a single sentence, and while I just skimmed over it at the time, today we might want to dive in a little deeper and see how itVisualize and develop AI capabilitiesJust how powerful!
Today we are going to discuss the topic of developing aGun games-inspired by the classic Crossfire. And why I chose to use the Tencent Cloud development platform todayCloudBase To realize this dream? Because, CloudBase is built onLowering the development threshold and increasing development efficiencyAs a promotional highlight, it provides a variety of tools and AI capabilities to help developers quickly realize their projects, and even some beginners who are not familiar with programming can easily get started. Therefore, today I decided to use this platform to fulfill a dream I had buried in my heart when I first graduated from university: to develop a game of my own.
Of course, time was limited and the project couldn't get too big, so we decided to leave 3D development out of the equation for the time being - after all, we're mainly developing for front-end PC pages, so that the game's presentation will be centered around the2DExpand. Although we are not going the 3D route, we will still strive to achieve a fulfilling gameplay experience in 2D graphics, adding some interesting interactive elements and innovative gameplay.
So, without further ado.The game development journey has officially begun!
Visual Cloud Development
preliminary
We do not beat around the bush, directly into the subject. If you have not opened the Tencent cloud services, simply go to the Tencent cloud console, search for "cloud development" and follow the prompts to complete the opening can be, the whole process is simple and intuitive, very easy to get started. As this part of the content is more basic, no longer in the article to explain in detail. As shown in the figure:
After completing the necessary environmental preparations, we can directly click into the relevant page to start the subsequent operation. As shown in the figure:
After entering the environment, we directly select the "Visual Development" option to start building the AI-driven website.
Okay, all the preliminary preparations have been successfully completed, then we officially enter the theme - start building the gun game. It should be noted that during the building process, we will encounter many problems and challenges, involving the implementation and fixing of a series of features such as picture sliding, collimator targeting, page optimization and so on. Although these details are important, if we list and discuss them one by one, the content of the article will be too long and cumbersome.
Therefore, the core purpose of this post is to teach you how to use building techniques to solve these problems and help you get your game built efficiently, rather than focusing on each specific minor problem.
Start building game
By default, the cloud development platform contains several intelligent body assistants, users can call the corresponding assistant function by @ tag according to the actual demand. Please refer to the following figure for the specific operation method:
We will directly use the AI generation component provided by default in order to quickly test its effect and performance performance. As shown in the figure:
If you're not completely satisfied with the results of your current page, you can always continue to ask questions and let the AI assistant help you beautify and adjust the page. However, it's worth noting that while AI can be of great help in terms of optimization and design, it can't completely replace your work. In fact, it can replace up to about 70% of your workload, which is already a pretty good performance.
Keep in mind that AI writes code from scratch when generating content, rather than accepting and updating it line by line, so the results may vary each time. When you see a page that is close to ideal, you can simply create the application and make subsequent optimizations and adjustments to ensure that the final result meets your needs. The process is shown below:
library
picture material
When you are in the process of creating a website, you usually need to use a large number of images, charts and various other material resources, before you start website development, you can upload these materials to the platform or server in advance, so as to follow up with more efficient page design and content integration. The following figure shows the specific steps or examples of this operation:
However, at the moment, you still can't select these images directly when building your website. Therefore, your main task is to copy the image links here. Of course, it would be better if you have your own image bed, because then you can not only use your own image resources directly, but also update the image content at any time. It is important to note that the gallery provided here does not allow for image update operations, only deletion or re-uploading. Therefore, this point may become a stuck point in your operation.
Music/video clips
At the moment, the cloud development material library does not support adding music or video files for the time being, but if you have such needs, you can completely solve them in other ways. Specifically, you can choose to use your own server and expose the files through it. It's not complicated, and I've gone ahead and configured it for you. All you need to do is install and configure a Nginx service on your own server and prepare a special folder for the footage files.
This way, you can easily provide audio or video files to your cloud development library by enabling file access and management through Nginx.
Step 1: Install nginx
Here I use the Pagoda panel that comes with Tencent Cloud Lightweight Server, you just need to quickly complete the installation through the one-click installation function, the installation process is very simple, the specific steps are shown in the figure:
Step 2: Prepare the clip folder
We just need to directly create an empty folder as a directory to store material files, convenient for subsequent material management and operation. As shown in the figure:
Step 3: Configure Nginx Reverse Generation
The last step, we directly configure the nginx proxy, note that here you need to solve the cross-domain problem, otherwise Tencent cloud can not directly access our server. Configuration is as follows:
# Static file services(photograph、audio frequency)
location /media/ {
alias /data/disk/media/; # Directory where media files are stored
try_files $uri $uri/ =404; # Returns if the file does not exist404
# CORS configure
add_header Access-Control-Allow-Origin *; # Allow access to all domains
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; # permissible HTTP methodologies
add_header Access-Control-Allow-Headers 'Origin, X-Requested-With, Content-Type, Accept, Authorization'; # permissiblerequesting头
add_header Access-Control-Max-Age 3600; # Cache time for preflight requests,In seconds.
# deal with OPTIONS requesting(用于预检requesting)
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'Origin, X-Requested-With, Content-Type, Accept, Authorization';
add_header Access-Control-Max-Age 3600;
return 204; # 对预检requesting返回 204 No Content
}
access_log /www/wwwlogs/;
}
Please paste this part of the code directly into the server module you want to listen to. This way we can test it directly in the browser to see if it works. As you can see in the picture:
Okay, after some organizing and preparation, we basically have all of our footage ready to go. Next, our focus will turn to how to use these materials effectively and maximize their potential.
Of course, in addition to those complex solutions, I'd like to share with you next some simple solutions in cloud development that can fulfill the needs while remaining efficient and flexible.
cloud storage
Each package has its fixed amount of storage. For example, in the case of my Personal Development Edition, it provides approximately 2GB of storage, which is more than enough for most daily development needs. If you find that the storage space is not enough for your needs during actual use, don't worry. You can follow the previously mentioned steps to build additional storage solutions on your own to ensure that you can flexibly cope with growing data storage needs.
You can use it exactly as your own folder. However, it is important to note that the cloud storage platform does not allow the name of the folder or file to be changed. Therefore, before uploading a file, unless there is a special need, it is recommended to change the Chinese name of the folder or file to English or other characters. As shown in the picture:
All we need is this temporary link, after getting this link, you can use the related resources normally, the whole process is very simple and intuitive. In addition to providing the basic link function, Cloud Function also has a very important feature, that is, it supports cache settings and CDN acceleration, which means that it can significantly improve the speed and efficiency of file access, reduce latency and optimize the user experience. As shown in the figure:
How to use
For example, if we wish to add a music playback component to an existing interface, we can refer to the illustration shown below:
Therefore, we only need to enter the corresponding file path in the URL bar, and the system will automatically recognize and load the required resources. Please refer to the diagram below for the procedure:
If you have filled in the URL path correctly, but still cannot play the music properly, or encounter the error situation shown in the figure below, then it is most likely due to cross-domain issues. As shown in the figure:
Here's another thing to note in particular: if you want your music to play automatically (such as the background music I've set up), you have to make sure that the music player component is visible. If the player component is hidden or not shown, the music will not be able to play automatically, as shown here:
Using images is very easy, you can embed them in an image container or add them as a background. As shown in the picture, the method of operation is intuitive and flexible.
There are no more tips here about the material. Let's move on.
New page
Of course, our app doesn't just rely on a single page for its entire functionality. After all, for a shooting game, a single page design is far from enough. Our game page will consist of three main sections: first, the Web Introduction page, which is used to display the basic information and features of the game; next, the Map Selection page, where players can choose their favorite battle maps; and lastly, the Game Combat page, where the player enters the actual battle scenario.
Therefore, we can use AI technology to further optimize and generate these pages to ensure that each page has the best user experience and functionality, as shown below:
After the generation is complete, we can select the corresponding page here and make selective edits and adjustments as needed. As shown in the figure below:
How to import the original page
Here we have some problems. For example, if I already have a ready-made HTML page, how do I import it in? The current structure here is built completely from scratch, without any ready-made import function. So, what should I do in this situation? Actually, there is a solution here - the JSX module. As shown in the picture:
When using JSX to import an existing page, it is especially important to note that the target page must be an empty page and cannot contain any components. The reason for this is that JSX handles the creation and rendering of components automatically. If other components already exist in the target page, it may cause conflicts or affect the rendering effect. Therefore, to avoid unnecessary errors or confusion, make sure the target page is clean and blank when imported.
Next, we will demonstrate step-by-step how to import an existing page into JSX. To simplify the demonstration process, I'm using a raw HTML file here rather than a complex page that integrates various front-end frameworks.
Below is the content of the original HTML file:
When a page contains a lot of commonly used CSS, JavaScript, and a variety ofdiv
When it comes to containers, if we choose to manually copy and paste them one by one into a new project, this approach is not only inefficient, but also wastes almost as much time as designing and building a whole new page from scratch. In this case, intelligent tools and AI assistants are especially important. For example, Tencent's Hybrid AI Assistant can significantly improve our development efficiency.
To do this, we only need to provide the AI with a reference example, similar to what is shown in the diagram, and the AI assistant will be able to intelligently analyze, extract and generate the required code structure. This not only saves a lot of time and energy, but also ensures the consistency and efficiency of the code, greatly improving the workflow and quality of development.
Next, you need to provide the full HTML code to the AI assistant, along with the corresponding JSX syntax examples. This will basically get you up and running. Be careful not to overload the page with too much content, as too much complexity can lead to errors during the import process. The result looks like the following:
As you can see, I'm not using multiple components here, just a simple JSX component. So, the question is, what should we do with our original JavaScript event handling and CSS styles? Actually, all of this is already implemented in JSX.
In this way, we can not only keep the original logic, but also embed JavaScript events and styles directly into the JSX code, making the whole component more compact and easy to manage. This is shown in the following figure:
click event
buttons
We can add all types of event responses to our components, not just limited to buttons. In fact, almost any component can be bound to event handlers, including text boxes, images, links, and even custom components. For example, a very common requirement is to add click events to buttons so that they can jump to a specified built-in page when clicked.
photograph
However, it is worth noting that in our map selection page, the user interaction is by clicking on the image to make a selection. Nonetheless, there is still a click event triggering mechanism for the image, as shown in the figure:
jump to a new page
I will briefly explain the part about page jumping, other functions are not covered for the time being. Normally, you can choose to do the page jump operation within this application in the following way:
For the use of external links, simply use the jump page function provided above to easily realize the jump operation.
JSX Components
This part of the work can be completely left to the AI assistant, after all, we have asked the AI assistant many times. On each query, the cloud development assistant will regenerate the JSX code according to our request, as shown below.
To avoid losing your current progress, if you are in a satisfactory situation, remember to press and hold theCTRL+S Shortcut keys to save the file. Doing so not only ensures that your work product is retained in a timely manner, but also makes it easy to roll back to the saved version of the source code if needed in the future. Below is a schematic of how rolling back to a historical version after saving works:
keystroke listener
Similarly, for more complex customizations and interactions, we can use JSX to write event listeners, such as key presses, in addition to regular JavaScript code. Although the official documentation mainly provides the implementation of mouse click events, in some specific scenarios, such as the need to exit the game by pressing the ESC key in my game, such needs cannot be satisfied by click events alone. Therefore, for these specific needs, we can write the corresponding key-listening logic directly in the JSX code. This is shown in the figure:
JSX Component Syntax
In the image above, you may have noticed that when I listen to theESC When the key is pressed, a method is triggered that directly displays a popup window. The popup is implemented using the built-in JSX component syntax, which has many varieties and features that make it easy to build interactive UI elements. For more detailed information on component usage and API documentation, see the following links:CloudBase Documentation - Tools API。
There are a number of specific syntaxes, as shown here:
Each one has a specific example demo, just copy it.
Game View Source Code
Ok, here I will share my current implementation of the game's viewpoint. If you're interested, you can dive into the entire gameplay process, including the specific implementation of page rendering, sound processing, and gun-holding perspectives. Below is the relevant code showing how I programmatically implemented these features. I hope this can bring you some inspiration, if you have any questions, please feel free to discuss together!
import React, { useEffect, useRef, useState } from 'react';
export default function ImageDisplay(props) {
const containerRef = useRef(null);
const imageRef = useRef(null);
const enemiesContainerRef = useRef(null);
const [enemies, setEnemies] = useState([]);
const [modalImage, setModalImage] = useState(null); // New Status,Used to control pop-up images
const audioRef = useRef(null); // Creating Audio References
const audioRef2 = useRef(null); // Creating Audio References
const enemyImages = [
"/resources/2024-12/lowcode-2054301",
"/resources/2024-12/lowcode-2054312"
];
// Mouse following effect
useEffect(() => {
const container = ;
const image = ;
const enemiesContainer = ;
let offsetX = 0;
let offsetY = 0;
const handleMouseMove = (e) => {
const containerRect = ();
const mouseX = - ;
const mouseY = - ;
const centerX = / 2;
const centerY = / 2;
offsetX = (centerX - mouseX) * 0.05;
offsetY = (centerY - mouseY) * 0.05;
= `translate(-50%, -50%) translate(${offsetX}px, ${offsetY}px)`;
= `translate(-50%, -50%) translate(${offsetX}px, ${offsetY}px)`;
};
const handleMouseLeave = () => {
= 'translate(-50%, -50%)';
= 'translate(-50%, -50%)';
};
('mousemove', handleMouseMove);
('mouseleave', handleMouseLeave);
// Clear event listeners
return () => {
('mousemove', handleMouseMove);
('mouseleave', handleMouseLeave);
};
}, []);
// Add Enemy
const addEnemy = () => {
const randomEnemyImage = enemyImages[(() * )];
const containerRect = ();
const imageRect = ();
// Get Container Center90%Size of the area
const centerWidth = * 0.9;
const centerHeight = * 0.9;
// Calculate the range of placeable enemies,bring to light90%regional
const maxX = centerWidth - 50; // Subtract the width of the enemy icon
const maxY = centerHeight - 50; // Subtract the height of the enemy icon
const minX = ( - centerWidth) / 2;
const minY = ( - centerHeight) / 2;
// Generate Random Positions,cap90%regional
const randomX = minX + () * maxX;
const randomY = minY + () * maxY;
const newEnemy = {
id: (),
image: randomEnemyImage,
x: randomX,
y: randomY
};
setEnemies((prevEnemies) => [...prevEnemies, newEnemy]);
setTimeout(() => {
setEnemies((prevEnemies) => (enemy => !== ));
}, 5000);
};
useEffect(() => {
const intervalId = setInterval(addEnemy, 3000);
return () => clearInterval(intervalId);
}, []);
// Clicking on an enemy event handler
const handleEnemyClick = (enemyId, enemyImage) => {
// Remove Enemy
setEnemies((prevEnemies) => (enemy => !== enemyId));
// Setting up a popup image and displaying it 1 Disappears automatically after a second
setModalImage('/resources/2024-12/lowcode-2054324');
// Reset the audio playback progress to0
if () {
= 0; // Reset audio playback progress
= 1; // Setting the volume to maximum
().catch((error) => {
("Audio playback failure", error);
});
}
setTimeout(() => {
setModalImage(null); // 1 Clear pop-up image after seconds
}, 1000);
};
// monitorESCkeystrokes
useEffect(() => {
const handleKeyDown = (e) => {
if ( === 'Escape') {
// Trigger modal popups
$({
title: 'Game Tips',
content: 'It's a modal popup.',
success(res) {
if () {
('The user clicks OK');
} else if () {
('User clicks to cancel');
}
},
});
}
};
('keydown', handleKeyDown);
// Clear event listeners
return () => {
('keydown', handleKeyDown);
};
}, []);
// Play sound effects with each mouse click
useEffect(() => {
const handleMouseClick = () => {
// Reset the audio playback progress to0
if () {
= 0; // Reset audio playback progress
= 1; // Setting the volume to maximum
().catch((error) => {
("Audio playback failure", error);
});
}
};
// existdocument上monitor点击事件
('click', handleMouseClick);
// Clear event listeners
return () => {
('click', handleMouseClick);
};
}, []);
return (
<div
ref={containerRef}
style={{
position: 'fixed', // utilizationfixedbring it up to full screen
top: 0,
left: 0,
width: '100vw',
height: '100vh',
overflow: 'hidden', // Disable scrollbars
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f0f0f0',
margin: 0, // Make sure there are no extra margins
padding: 0, // Make sure there are no extra inside margins
boxSizing: 'border-box', // Ensure element size includes margins and inner margins
cursor: 'url(/resources/2024-12/lowcode-2051938), crosshair', // Setting up a custom cursor
}}
>
<div
style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '120%',
height: '120%',
overflow: 'visible',
}}
>
<img
ref={imageRef}
src="/resources/2024-12/lowcode-2051969"
alt="Image"
style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '100%',
height: '100%',
transition: 'transform 0.1s ease',
zIndex: -1, // Background image
}}
/>
</div>
<div
ref={enemiesContainerRef}
style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '100%',
height: '100%',
overflow: 'visible',
}}
>
{((enemy) => (
<div
key={}
style={{
position: 'absolute',
width: '80px',
height: '80px',
backgroundImage: `url(${})`,
backgroundSize: 'cover',
left: `${}px`,
top: `${}px`,
cursor: 'url(/resources/2024-12/lowcode-2051938), crosshair', // Maintaining the collimator cursor
pointerEvents: 'auto', // Ensure that the enemy icon receives events
}}
onClick={() => handleEnemyClick(, )} // Click on the enemy
/>
))}
</div>
{/* Pop-up picture(Click on the enemy时展示) */}
{modalImage && (
<img
src={modalImage}
alt="Modal Image"
style={{
position: 'absolute',
top: '85%',
left: '50%',
transform: 'translate(-50%, -85%)',
width: '70px',
height: '70px',
zIndex: 1000, // 确保弹出的图片exist最上层
}}
/>
)}
{/* Bottom centered image */}
<img
src="/resources/2024-12/lowcode-2054553"
alt="Bottom Center Image"
style={{
position: 'absolute',
bottom: '1px', // 固定exist底部,Distance to bottom20px
left: '60%',
transform: 'translateX(-60%)', // center
width: '350px', // Fixed width of50px
height: '350px', // Fixed height of50px
zIndex: 1, // Make sure it's on top
}}
/>
{/* Sound Files,audio element */}
<audio ref={audioRef} src="https://domain name/media/shut.mp3" />
{/* Sound Files,audio element */}
<audio ref={audioRef2} src="https://domain name/media/laught.mp3" />
</div>
);
}
All of them are ready to run except for the last two audio files you need to replace with your own.
game effect
The exciting moment has finally arrived, my game is finally finished! After countless hours of design, development and tweaking, this moment has finally arrived.
Experience Address:/7h1hex26/preview/?envType=preview
I recorded a video to better demonstrate the background sound effects, page jumps, and other interactive elements of the game.
/developer/video/81621
summarize
As the journey of game development draws to a close, we can't help but marvel at the power and convenience of Tencent Cloud's CloudBase platform for development. From the initial page construction to the implementation of complex game perspectives, CloudBase, with its AI-driven visualization development tools, made the entire development process exceptionally efficient. It not only lowers the technical threshold, but also greatly improves the development efficiency, making it possible for even beginners to quickly get started and realize their creativity.
During the process, I experienced every step from material preparation to page construction, and felt the advantages of CloudBase in simplifying the development process and providing rich components and tools. Whether it is uploading and managing image materials or integrating music and video materials, CloudBase provides an intuitive interface and flexible solutions. It is especially worth mentioning that through JSX components and event listeners, we can easily realize complex interaction logic, such as key listening and page jumping, which greatly enriches the playability and user experience of the game.
With CloudBase, we not only realized a simple 2D shooter game, but more importantly, we mastered a new way of development, which combines AI capabilities with cloud services, providing unlimited possibilities for future project development.
Finally, I hope that this article will inspire more developers to join CloudBase and use this platform to realize their creativity and dreams.
I'm Rain, a Java server-side coder, studying the mysteries of AI technology. I love technical communication and sharing, and I am passionate about open source community. I am also a Tencent Cloud Creative Star, Ali Cloud Expert Blogger, Huawei Cloud Enjoyment Expert, and Nuggets Excellent Author.
💡 I won't be shy about sharing my personal explorations and experiences on the technology path in the hope that I can bring some inspiration and help to your learning and growth.
🌟 Welcome to the effortless drizzle! 🌟