Pin the Dexcom Simulation
- Game Development Journal: Pin the Dexcom on the Human
Game Development Journal: Pin the Dexcom on the Human
Project Overview
Game Title: Pin the Needle
Genre: Medical Education Simulation
Target Audience: Nursing students & diabetic patients
Development Period: April - June 2025
Tech Stack:
- Frontend: HTML5 Canvas, CSS3, JavaScript (ES6+)
- Backend: Python Flask, SQLAlchemy
- Database: SQLite (Development), PostgreSQL (Production)
Phase 1: Design & Planning
Core Learning Objectives
- Teach proper CGM sensor placement according to FDA guidelines
- Visualize subcutaneous tissue layers for better understanding
- Reduce anxiety in first-time CGM users through gamification
User Stories
- As a player, I want to drag and drop a Dexcom device onto a virtual human model, So that I can learn the correct placement for a continuous glucose monitor.
Frontend Wireframe
Key Elements:
- Drag-and-drop sensor interface
- Real-time anatomical feedback
- Scoring system based on placement accuracy
Phase 2: Frontend Development
Core Implementation
1. Drag-and-Drop System
// Enhanced drag handling with collision detection
class DexcomDragger {
constructor() {
this.sensor = document.getElementById('dexcom-sensor');
this.dropZones = document.querySelectorAll('.placement-zone');
this.initDragEvents();
}
initDragEvents() {
this.sensor.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', 'dexcom-sensor');
this.highlightValidZones();
});
document.addEventListener('dragover', (e) => {
e.preventDefault();
this.updateGhostPosition(e.clientX, e.clientY);
});
document.addEventListener('drop', (e) => {
e.preventDefault();
this.handleDrop(e);
});
}
handleDrop(e) {
const dropZone = this.findDropZone(e.clientX, e.clientY);
if (dropZone && dropZone.dataset.valid === 'true') {
this.showSuccessFeedback(dropZone.dataset.anatomy);
} else {
this.showErrorFeedback();
}
}
}
2. Real-Time Feedback System
function showAnatomicalFeedback(zone) {
const layers = {
'abdomen': ['skin', 'fat', 'muscle'],
'arm': ['skin', 'connective-tissue']
};
renderTissueLayers(layers[zone]);
displayMedicalRationale(zone);
}
3. Responsive Design Solution
/* Mobile-first approach */
.placement-zone {
position: absolute;
width: 15vw;
height: 15vw;
border-radius: 50%;
opacity: 0.3;
transition: all 0.3s ease;
&[data-valid="true"] {
background: rgba(46, 204, 113, 0.3);
&:hover {
opacity: 0.6;
}
}
}
@media (pointer: coarse) {
/* Touch device optimizations */
.sensor {
touch-action: none;
width: 80px !important;
}
}
Phase 3: Backend Development
Database Schema
class GlucoseRecord(db.Model):
__tablename__ = 'glucose_records'
id = db.Column(db.Integer, primary_key=True)
value = db.Column(db.Float, nullable=False)
time = db.Column(db.DateTime, nullable=False)
notes = db.Column(db.String(500))
status = db.Column(db.String(10), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
API Endpoints
| Endpoint | Method | Description |
|———-|——–|————-|
| /api/glucose
| GET | Fetch all records |
| /api/glucose
| POST | Create new record |
| /api/glucose/<id>
| PUT | Update record |
| /api/glucose/<id>
| DELETE | Remove record |
CRUD Operations
# Flask API Example
@glucose_api.route('/', methods=['POST'])
def create_record():
try:
data = request.get_json()
validate_glucose_data(data) # Custom validation
new_record = GlucoseRecord(
value=data['value'],
time=datetime.fromisoformat(data['time']),
notes=data.get('notes', ''),
status=get_glucose_status(data['value'])
)
db.session.add(new_record)
db.session.commit()
return jsonify(new_record.read()), 201
except ValueError as e:
return jsonify({"error": str(e)}), 400
Phase 4: Integration Challenges
Problem: Mobile Touch Inaccuracy
Solution: Implemented touch-specific coordinates calculation
function handleTouchMove(e) {
const touch = e.touches[0];
const rect = canvas.getBoundingClientRect();
return {
x: touch.clientX - rect.left,
y: touch.clientY - rect.top,
pressure: touch.force || 0.5
};
}
Problem: Database Race Conditions
Solution: Added SQLAlchemy session locking
with db.session.begin():
record = GlucoseRecord.query.with_for_update().get(record_id)
record.value = new_value
db.session.commit()
Educational Takeaways
For Future Students
- Start Simple: Begin with mock JSON data before backend integration
- Test Early: Use BrowserStack for cross-device drag-and-drop testing
- Document APIs: Use Swagger UI for API documentation
Code Review Highlights
✅ Well-structured Flask Blueprints
✅ Proper error handling in CRUD operations
🔧 Improvement Opportunity: Add JWT authentication
🔧 Improvement Opportunity: Implement undo functionality
Project Resources
Future Roadmap
- AR Mode using TensorFlow.js
- Multiplayer Practice Mode
- Certification Badge System